服务器
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<string.h>
#define ERR_MSG(msg) do{\
fprintf(stderr,"__%d__",__LINE__);\
perror(msg);\
}while(0)
typedef struct node //创建链表,存储是谁发送给我消息
{
struct sockaddr_in cin;
struct node *next;
}zzy;
int main(int argc, const char *argv[])
{
int sfd=socket(AF_INET,SOCK_DGRAM,0);
if(sfd<0)
{
ERR_MSG("socket");
return -1;
}
struct sockaddr_in sin; //填充服务器IP和端口
sin.sin_family=AF_INET;
sin.sin_port=htons(8888);
sin.sin_addr.s_addr=inet_addr("192.168.31.80");
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0) //绑定服务器地址结构体
{
ERR_MSG("bind");
return -1;
}
//创建结构体变量
zzy* s=(zzy*)malloc(sizeof(zzy));
s->next=NULL;
zzy* k=s;
socklen_t len=sizeof(k->cin);
char buf[137]=""; //存储发送的消息
printf("服务器开启\n");
while(1)
{
bzero(buf,sizeof(buf));
//接收客户端请求
if(recvfrom(sfd,buf,137,0,(struct sockaddr*)&(k->cin),&len)<0)
{
ERR_MSG("recvfrom");
return -1;
}
//存储是谁发送给我消息,头插存入链表
if(buf[0]==1)
{
zzy* q=(zzy*)malloc(sizeof(zzy));
q->next=s->next;
q->cin=k->cin;
s->next=q;
printf("%s\n",inet_ntoa(q->cin.sin_addr));
zzy* l=s->next;
//循环发送给所有客户端
while(1)
{
if(l->next==NULL)
break;
if(sendto(sfd,buf,137,0,(struct sockaddr*)&(l->next->cin),sizeof(l->next->cin))<0)
{
ERR_MSG("sendto");
return -1;
}
l=l->next;
}
}
else if(buf[0]==2)
{
zzy* l=s->next;
while(1)
{
if(l==NULL)
break;
if((l->cin)!=(k->cin))
{
if(sendto(sfd,buf,129,0,(struct sockaddr*)&(l->cin),sizeof(l->cin))<0)
{
ERR_MSG("sendto");
return -1;
}
}
l=l->next;
}
}
else if(buf[0]=3)
{
zzy* l=s->next;
while(1)
{
if(l->next==NULL)
break;
if(sendto(sfd,buf,137,0,(struct sockaddr*)&(l->cin),sizeof(l->cin))<0)
{
ERR_MSG("sendto");
return -1;
}
l=l->next;
}
zzy* h=s;
while(h->next!=k)
{
h=h->next;
}
zzy* y=h->next;
h->next=y->next;
free(y);
y=NULL;
printf("删除成功");
}
else
{
printf("操作码错误");
}
}
return 0;
}
客户端
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<string.h>
#define ERR_MSG(msg) do{\
fprintf(stderr,"__%d__",__LINE__);\
perror(msg);\
}while(0)
int main(int argc, const char *argv[])
{
int sfd=socket(AF_INET,SOCK_DGRAM,0);
if(sfd<0)
{
ERR_MSG("socket");
return -1;
}
struct sockaddr_in sin; //填充服务器IP地址和端口
sin.sin_family=AF_INET;
sin.sin_port=htons(8888);
sin.sin_addr.s_addr=inet_addr("192.168.31.80");
char buf[137]=""; //发送的消息
printf("请输入名字->");
scanf("%s",buf+1);
strcat(buf+1,"上线");
buf[0]=1;
if(sendto(sfd,buf,137,0,(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("sendto");
return -1;
}
pid_t pid=fork(); //创建子进程
socklen_t len=sizeof(sin);
while(1)
{
if(pid>0)
{
bzero(buf,sizeof(buf));
if(recvfrom(sfd,buf,137,0,(struct sockaddr*)&sin,&len)<0)
{
ERR_MSG("recvfrom");
return -1;
}
if(buf[0]==1)
{
printf("%s\n",buf+1);
}
if(buf[0]==2)
{
printf("%s\n",buf+2);
}
if(buf[0]==3)
{
strcat(buf+1,"下线");
printf("%s\n",buf+1);
}
}
else if(pid==0)
{
bzero(buf,sizeof(buf));
fgets(buf+2,128,stdin);
buf[strlen(buf)-1]=0;
buf[0]=2;
if(sendto(sfd,buf,137,0,(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("sendto");
return -1;
}
if(strcmp(buf+2,"quit")==0)
exit(0);
}
}
return 0;
}