#include<myhead.h>
#define G_IP "224.2.1.1"
#define PORT 8888
#define LOC_IP "192.168.114.114"
#define PASSWD_PATH "./Password.txt"
///注册函数:打包regist_apply
char * regist(char *regist_apply)
{
char account[24]="";
char passwd[24]="";
printf("请输入6位账号:");
scanf("%s",account);
printf("请输入6位密码:");
scanf("%s",passwd);
strcat(account,passwd);
strcat(regist_apply,account);
return regist_apply;
}
///登录函数;打包login_apply
char * login(char *login_apply)
{
char account[24]="";
char passwd[24]="";
printf("请输入6位账号:");
scanf("%s",account);
printf("请输入6位密码:");
scanf("%s",passwd);
strcat(account,passwd);
strcat(login_apply,account);
return login_apply;
}
int main(int argc, const char *argv[])
{
int srfd;
if((srfd=socket(AF_INET,SOCK_DGRAM,0))<0)
{
ERR_MSG("socket");
return -1;
}
//加入多播组,能收到组内成员的消息
/* struct ip_mreqn mq;
mq.imr_multiaddr.s_addr=inet_addr(G_IP);
mq.imr_address.s_addr=inet_addr(LOC_IP);
mq.imr_ifindex=0;
if(setsockopt(srfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mq,sizeof(mq))<0)
{
ERR_MSG("setsockopt");
return -1;
}*/
///端口复用
int reuse=1;
if(setsockopt(srfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
{
ERR_MSG("setsockopt");
return -1;
}
///允许广播
int broad=1;
if(setsockopt(srfd,SOL_SOCKET,SO_BROADCAST,&broad,sizeof(broad))<0)
{
ERR_MSG("setsockopt");
return -1;
}
///不接收自身的消息
int loop=0;
if(setsockopt(srfd,IPPROTO_IP,IP_MULTICAST_LOOP,&loop,sizeof(loop))<0)
{
ERR_MSG("setsockopt");
}
struct sockaddr_in G_addr,SOUR_addr;
G_addr.sin_family=AF_INET;
G_addr.sin_port=htons(PORT);
G_addr.sin_addr.s_addr=inet_addr(G_IP);
socklen_t addrlen=sizeof(SOUR_addr);
///绑定本地组播IP与收发套接字
if(bind(srfd,(struct sockaddr*)(&G_addr),sizeof(G_addr))<0)
{
ERR_MSG("bind");
return -1;
}
struct pollfd fds[2];
memset(fds,0,sizeof(fds));
fds[0].fd=0;
fds[0].events=POLLIN;
fds[1].fd=srfd;
fds[1].events=POLLIN;
nfds_t nfds=2;
int res;//poll的返回值
ssize_t ret=0;
char buf[128]="";
char online[128]="----已上线----\n";
char regist_apply[48]="--regist apply--";
char login_apply[48]="--login apply--";
while(1)
{
printf("1)登录\n");
printf("2)注册\n");
int choice;
scanf("%d",&choice);
while(getchar()!=10);
switch(choice)
{
case 1:
bzero(buf,sizeof(buf));
login(login_apply);
//发送登录请求信息
if(sendto(srfd,login_apply,strlen(login_apply),0,(struct sockaddr*)(&G_addr),sizeof(G_addr))<0)
{
ERR_MSG("sendto");
return -1;
}
bzero(buf,sizeof(buf));
//接受服务器返回的登录是否成功信息
recvfrom(srfd,buf,sizeof(buf),0,(struct sockaddr*)(&SOUR_addr),&addrlen);
printf("%s\n",buf);
//接受到成功
if(strcmp(buf,"--login apply--success")==0)
{
if(sendto(srfd,online,strlen(online),0,(struct sockaddr*)(&G_addr),sizeof(G_addr))<0)
{
ERR_MSG("sendto");
return -1;
}
printf("---登录成功---\n");
goto chat;
}
//接收到失败
if(strcmp(buf,"--login apply--fail")==0)
{
printf("---登录失败,账号或密码错误---\n");
}
break;
case 2:
bzero(buf,sizeof(buf));
regist(regist_apply);
//发送注册请求消息
if(sendto(srfd,regist_apply,strlen(regist_apply),0,(struct sockaddr*)(&G_addr),sizeof(G_addr))<0)
{
ERR_MSG("sendto");
return -1;
}
printf("注册成功\n");
break;
}
}
chat:
while(1)
{
res=poll(fds,nfds,-1);
if(res<0)
{
ERR_MSG("poll");
return -1;
}
else if(res>0)
{
//终端输入事件发生
if(fds[0].revents&POLLIN)
{
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1]=0;
if(sendto(srfd,buf,strlen(buf),0,(struct sockaddr*)(&G_addr),sizeof(G_addr))<0)
{
ERR_MSG("sendto");
return -1;
}
}
//接收到消息
if(fds[1].revents&POLLIN)
{
// printf("接受\n");
bzero(buf,sizeof(buf));
ret=recvfrom(srfd,buf,sizeof(buf),0,(struct sockaddr*)(&SOUR_addr),&addrlen);
if(ret<0)
{
ERR_MSG("recvfrom");
return -1;
}
//忽略注册和登录申请
if((strncmp(buf,"--regist apply--",16)==0)||(strncmp(buf,"--login apply--",15)==0))
{
continue;
}
printf("%s[%d]:%s\n",inet_ntoa(SOUR_addr.sin_addr),ntohs(SOUR_addr.sin_port),buf);
}
}
}
return 0;
}
#include<myhead.h>
#define G_IP "224.1.1.1"
#define PORT 8888
#define SER_IP "192.168.114.137"
#define PASSWD_PATH "./Password.txt"
#define RECORD_FILE "./record.txt"
//时间函数,在记录文件中写入当前时间
int record_time(FILE*fp)
{
time_t timer;
struct tm *NOW;
timer=time(NULL);
NOW=localtime(&timer);
fprintf(fp,"%d_%d_%d_%d_%d_%d\n",NOW->tm_year+1900,NOW->tm_mon+1,NOW->tm_mday,NOW->tm_hour,NOW->tm_min,NOW->tm_sec);
}
//记录函数,将全部信息存入日记文档
int recordit(FILE*fp,char buf[128],struct sockaddr_in SOUR_addr)
{
if(fprintf(fp,"%s[%d]:%s\n",inet_ntoa(SOUR_addr.sin_addr),ntohs(SOUR_addr.sin_port),buf)<0)
{
ERR_MSG("fprintf");
return -1;
}
return 0;
}
int main(int argc, const char *argv[])
{
FILE *fp_re;//记录文件的文件指针
FILE *fp_passwd;//密码文件的文件指针
if((fp_passwd=fopen(PASSWD_PATH,"a+"))<0)
{
ERR_MSG("fopen");
return -1;
}
if((fp_re=fopen(RECORD_FILE,"a"))<0)
{
ERR_MSG("fopen");
return -1;
}
int srfd;
if((srfd=socket(AF_INET,SOCK_DGRAM,0))<0)
{
ERR_MSG("socket");
return -1;
}
//加入多播组,能收到组内成员的消息
struct ip_mreqn mq;
mq.imr_multiaddr.s_addr=inet_addr(G_IP);
mq.imr_address.s_addr=inet_addr(SER_IP);
mq.imr_ifindex=0;
if(setsockopt(srfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mq,sizeof(mq))<0)
{
ERR_MSG("setsockopt");
return -1;
}
//端口复用
int reuse=1;
if(setsockopt(srfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
{
ERR_MSG("setsockopt");
return -1;
}
//允许广播
int broad=1;
if(setsockopt(srfd,SOL_SOCKET,SO_BROADCAST,&broad,sizeof(broad))<0)
{
ERR_MSG("setsockopt")
return -1;
}
struct sockaddr_in G_addr,SOUR_addr;
G_addr.sin_family=AF_INET;
G_addr.sin_port=htons(PORT);
G_addr.sin_addr.s_addr=inet_addr(G_IP);
socklen_t addrlen=sizeof(SOUR_addr);
//绑定收发套接字和广播IP
if(bind(srfd,(struct sockaddr*)(&G_addr),sizeof(G_addr))<0)
{
ERR_MSG("bind");
return -1;
}
struct pollfd fds[2];
memset(fds,0,sizeof(fds));
fds[0].fd=0;
fds[0].events=POLLIN;
fds[1].fd=srfd;
fds[1].events=POLLIN;
nfds_t nfds=2;
int res;//poll的返回值
ssize_t ret=0;
char buf[128]="";
char temp[48]="";
while(1)
{
res=poll(fds,nfds,-1);
if(res<0)
{
ERR_MSG("poll");
return -1;
}
else if(res>0)
{
//终端写入发送
if(fds[0].revents&POLLIN)
{
bzero(buf,sizeof(buf));
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1]=0;
if(sendto(srfd,buf,strlen(buf),0,(struct sockaddr*)(&G_addr),sizeof(G_addr))<0)
{
ERR_MSG("sendto");
return -1;
}
record_time(fp_re);
recordit(fp_re,buf,G_addr);
fflush(fp_re);
}
if(fds[1].revents&POLLIN)
{
// printf("接收\n");
bzero(buf,sizeof(buf));
ret=recvfrom(srfd,buf,sizeof(buf),0,(struct sockaddr*)(&SOUR_addr),&addrlen);
record_time(fp_re);
recordit(fp_re,buf,SOUR_addr);
fflush(fp_re);
if(ret<0)
{
ERR_MSG("recvfrom");
return -1;
}
if((strcmp(inet_ntoa(SOUR_addr.sin_addr),SER_IP)==0)&&(ntohs(SOUR_addr.sin_port)==PORT))
{
continue;
}
if(strncmp(buf,"--regist apply--",16)==0)
{
if(fwrite(buf+16,12,1,fp_passwd)<0)
{
ERR_MSG("fwrite");
return -1;
}
continue;
}
//收到登录申请
if(strncmp(buf,"--login apply--",15)==0)
{
fseek(fp_passwd,0,SEEK_SET);
//遍历密码文件
while(1)
{
bzero(temp,sizeof(temp));
fread(temp,12,1,fp_passwd);
printf("%s\n",temp);
//账号密码匹配
if(strcmp(temp,buf+15)==0)
{
if(sendto(srfd,"--login apply--success",22,0,(struct sockaddr*)(&G_addr),sizeof(G_addr))<0)
{
ERR_MSG("sendto");
return -1;
}
break;
}
//遍历结束未能匹配账号密码
if(feof(fp_passwd))
{
if(sendto(srfd,"--login apply--fail",19,0,(struct sockaddr*)(&G_addr),sizeof(G_addr))<0)
{
ERR_MSG("sendto");
return -1;
}
break;
}
}
}
printf("%s[%d]:%s\n",inet_ntoa(SOUR_addr.sin_addr),ntohs(SOUR_addr.sin_port),buf);
}
}
}
return 0;
}
ubuntu@ubuntu