📄 c.c
字号:
{
printf("the first letter of name isnot '!'\n");
exit(1);
}
if(strlen(argv[3]) > 10)
{
printf("the length of name is not more then 10 ");
exit(1);
}
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"Socket error:%s\n",strerror(errno));
exit(1);
}
strncpy(serviceip,argv[1],16);
// printf("service :%s",serviceip);
bzero(&server_addr,sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=inet_addr(argv[1]);
server_addr.sin_port=htons(PORT);
if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr)) == -1)
{
fprintf(stderr,"Connect error:%s\n",strerror(errno));
exit(1);
}
key=atoi(argv[3]);
seg_id=shmget(key,sizeof(struct client)*CLIENTNUMBER,IPC_CREAT | 0600);
if(seg_id == -1)
{
perror("shmget");
exit(1);
}
clients=(struct client *)shmat(seg_id,NULL,0);
for(i=0; i<CLIENTNUMBER; i++)
{
clients[i].state=0;
clients[i].count=0;
}
gethostname(hostname,30);
hp=gethostbyname(hostname);
inet_ntop(AF_INET,hp->h_addr,clientmsg.ip,16);
strncpy(clientmsg.name,argv[2],11);
clientmsg.state=1;
if(send(sockfd,&clientmsg,sizeof(struct clientmsg),0) != sizeof(struct clientmsg))
{
fprintf(stderr,"send error:%s\n",strerror(errno));
exit(1);
}
if(recv(sockfd,clients,sizeof(struct client)*CLIENTNUMBER,0) == -1)
{
fprintf(stderr,"recv error:%s\n",strerror(errno));
exit(1);
}
close(sockfd);
PrintClient(clients,CLIENTNUMBER);
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1)
{
fprintf(stderr,"Socket error:%s\n",strerror(errno));
exit(1);
}
if((recvpid=fork()) < 0)
{
fprintf(stderr,"fork error:%s\n",strerror(errno));
exit(1);
}
if(recvpid == 0)
{//recv
bzero(&recv_addr,sizeof(struct sockaddr_in));
recv_addr.sin_family=AF_INET;
recv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
recv_addr.sin_port=htons(CLIENTPORT);
if(bind(sockfd,(struct sockaddr*)(&recv_addr),sizeof(recv_addr)) == -1)
{
fprintf(stderr,"Bind error:%s\n",strerror(errno));
exit(1);
}
addr_len=sizeof(recv_addr);
while(1)
{
recv_len=recvfrom(sockfd,msg_buf,BUFSIZ,0,(struct sockaddr *)&recv_addr,&addr_len);
msg_buf[recv_len]='\0';
strncpy(recvip,inet_ntoa(recv_addr.sin_addr),16);
IpToName(clients,CLIENTNUMBER,recvname,recvip);
printf("%s say:%s\n",recvname,msg_buf);
}//while(1)
}//recv end
if((recvippid=fork()) < 0)
{
fprintf(stderr,"fork error:%s\n",strerror(errno));
exit(1);
}
if(recvippid == 0)
{//recvip
if((sockfdip=socket(AF_INET,SOCK_DGRAM,0))==-1)
{
fprintf(stderr,"Socket error:%s\n",strerror(errno));
exit(1);
}
bzero(&recv_addr,sizeof(struct sockaddr_in));
recv_addr.sin_family=AF_INET;
recv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
recv_addr.sin_port=htons(RECVIPPORT);
if(bind(sockfdip,(struct sockaddr*)(&recv_addr),sizeof(recv_addr)) == -1)
{
fprintf(stderr,"RecvIp Bind error:%s\n",strerror(errno));
exit(1);
}
addr_len=sizeof(recv_addr);
while(1)
{
recv_len=recvfrom(sockfdip,&clientmsg,sizeof(clientmsg),0,(struct sockaddr *)&recv_addr,&addr_len);
if(clientmsg.state == 1)
{
AddToClient(clients,CLIENTNUMBER,clientmsg);
printf("join name:%s\n",clientmsg.name);
}
else
{
DeleteToClient(clients,CLIENTNUMBER,clientmsg);
printf("leave name:%s\n",clientmsg.name);
}
}//while(1)
}//recvip end
else
{//send //father fork
SendToEveryone(clients,CLIENTNUMBER,sockfd,RECVIPPORT,clientmsg);
act.sa_handler=sigfunc;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask,SIGINT);
sigaddset(&act.sa_mask,SIGQUIT);
act.sa_flags=0;
if(sigaction(SIGINT,&act,NULL) < 0)
{
fprintf(stderr,"SIGINT error:%s",strerror(errno));
}
if(sigaction(SIGINT,&act,NULL) < 0)
{
fprintf(stderr,"SIGINT error:%s",strerror(errno));
}
while(1)
{
memset(msg_buf,0,sizeof(msg_buf));
fgets(msg_buf,BUFSIZ,stdin);
if((sendmsg=memchr(msg_buf,':',13)) == NULL)
{
printf("no name\n");
continue;
}
// printf("|%s|\n",sendmsg);
strncpy(sendname,msg_buf,sendmsg-msg_buf);
sendname[sendmsg-msg_buf]='\0';
if(strcmp(sendname,"!print") == 0)
{
PrintClient(clients,CLIENTNUMBER);
continue;
}
sendmsg++;
if(sendmsg == NULL)
{
printf("no message\n");
continue;
}
// printf("name:%s,ip:%s,msg,%s!\n",sendname,sendip,sendmsg);
if(strcmp(sendname,"!all") == 0)
{
SendMsgToEveryone(clients,CLIENTNUMBER,sockfd,CLIENTPORT,sendmsg);
continue;
}
if(NameToIp(clients,CLIENTNUMBER,sendname,sendip) == -1)
{
printf("have no the name\n");
continue;
}
bzero(&send_addr,sizeof(struct sockaddr_in));
send_addr.sin_addr.s_addr=inet_addr(sendip);
send_addr.sin_family=AF_INET;
send_addr.sin_port=htons(CLIENTPORT);
if(sendto(sockfd,sendmsg,strlen(sendmsg),0,(struct sockaddr *)&send_addr,sizeof(send_addr)) == -1)
{
fprintf(stderr,"send error:%s\n",strerror(errno));
}
}//while(1)
}//send end
}
void sigfunc(int signo)
{
int i;
int sockfd;
struct sockaddr_in send_addr;
clientmsg.state=0;
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1)
{
fprintf(stderr,"Socket error:%s\n",strerror(errno));
exit(1);
}
SendToEveryone(clients,CLIENTNUMBER,sockfd,RECVIPPORT,clientmsg);
bzero(&send_addr,sizeof(struct sockaddr_in));
send_addr.sin_addr.s_addr=inet_addr(serviceip);
send_addr.sin_family=AF_INET;
send_addr.sin_port=htons(RECVIPPORT);
if(sendto(sockfd,&clientmsg,sizeof(clientmsg),0,(struct sockaddr *)&send_addr,sizeof(send_addr)) == -1)
{
fprintf(stderr,"send error:%s\n",strerror(errno));
}
close(sockfd);
if(shmctl(seg_id,IPC_RMID,NULL) == -1)
{
printf("unlink msg queue error\n");
}
if(signal(SIGINT,SIG_DFL) == SIG_ERR)
{
fprintf(stderr,"SIGINT SIG_DFL error:%s\n",strerror(errno));
exit(1);
}
if(signal(SIGQUIT,SIG_DFL) == SIG_ERR)
{
fprintf(stderr,"SIGQUIT SIG_DFL error:%s\n",strerror(errno));
exit(1);
}
kill(getpid(),signo);
}
void AddToClient(struct client *clients,int numbers,struct clientmsg clientmsg)
{
int i,len,ch;
for(i=0; i<numbers; i++)
{
if(clients[i].state == 1)
{
if(strcmp(clients[i].name,clientmsg.name) == 0)
{
clients[i].count++;
len=strlen(clients[i].name);
if(clients[i].count < 10)
{
(clients[i].name)[len]=clients[i].count+48;
(clients[i].name)[len+1]='\0';
}
if(clients[i].count > 9)
{
(clients[i].name)[len]=clients[i].count/10+48;
(clients[i].name)[len+1]=clients[i].count%10+48;
(clients[i].name)[len+2]='\0';
}
AddToClient(clients,numbers,clientmsg);
clients[i].count=0;
return ;
}
}
}
for(i=0; i<numbers; i++)
{
if(clients[i].state == 0)
{
clients[i].state=1;
strncpy(clients[i].name,clientmsg.name,13);
strncpy(clients[i].ip,clientmsg.ip,16);
clients[i].count=0;
break;
}
}
}
void PrintClient(struct client *clients,int numbers)
{
int i;
for(i=0; i<numbers; i++)
{
if(clients[i].state == 1)
{
printf("name:%s ip:%s\n",clients[i].name,clients[i].ip);
}
}
}
int NameToIp(struct client *clients,int numbers,char *name,char *ip)
{
int i;
for(i=0; i<numbers; i++)
{
if(clients[i].state == 1)
{
if(strcmp(clients[i].name,name) == 0)
{
strncpy(ip,clients[i].ip,16);
return 0;
}
}
}
return -1;
}
int IpToName(struct client *clients,int numbers,char *name,char *ip)
{
static unnamenumber=0;
int i;
for(i=0; i<numbers; i++)
{
if(clients[i].state == 1)
{
if(strcmp(clients[i].ip,ip) == 0)
{
strncpy(name,clients[i].name,13);
return 0;
}
}
}
for(i=0; i<numbers; i++)
{
if(clients[i].state == 0)
{
strncpy(clients[i].ip,ip,16);
sprintf(clients[i].name,"unname%d",unnamenumber);
clients[i].state=1;
unnamenumber++;
strncpy(name,clients[i].name,13);
return 0;
}
}
}
void SendToEveryone(struct client *clients,int numbers,int sockfd,int port,struct clientmsg clientmsg)
{
int i;
struct sockaddr_in send_addr;
for(i=0; i<numbers; i++)
{
if(clients[i].state == 1)
{
bzero(&send_addr,sizeof(struct sockaddr_in));
send_addr.sin_addr.s_addr=inet_addr(clients[i].ip);
send_addr.sin_family=AF_INET;
send_addr.sin_port=htons(port);
if(sendto(sockfd,&clientmsg,sizeof(clientmsg),0,(struct sockaddr *)&send_addr,sizeof(send_addr)) == -1)
{
fprintf(stderr,"send error:%s\n",strerror(errno));
}
}
}
}
void SendMsgToEveryone(struct client *clients,int numbers,int sockfd,int port,char *msg)
{
int i;
struct sockaddr_in send_addr;
for(i=0; i<numbers; i++)
{
if(clients[i].state == 1)
{
bzero(&send_addr,sizeof(struct sockaddr_in));
send_addr.sin_addr.s_addr=inet_addr(clients[i].ip);
send_addr.sin_family=AF_INET;
send_addr.sin_port=htons(port);
if(sendto(sockfd,msg,sizeof(msg),0,(struct sockaddr *)&send_addr,sizeof(send_addr)) == -1)
{
fprintf(stderr,"send error:%s\n",strerror(errno));
}
}
}
}
void DeleteToClient(struct client *clients,int numbers,struct clientmsg clientmsg)
{
int i;
for(i=0; i<numbers; i++)
{
if(clients[i].state == 1)
{
if(strcmp(clients[i].ip,clientmsg.ip) == 0)
{
clients[i].state=0;
return ;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -