服务器端
#include <my.h>
#define SER_PORT 8888
#define SER_IP "192.168.125.27"
typedef struct lianbiao
{
struct sockaddr_in addr;
struct lianbiao*next;
}biao;
//客户端信息
typedef struct lian
{
int type;
char name[32];
char text[128];
}xinxi;
biao *fun()
{
biao*p=(biao *)malloc(sizeof(biao));
if(p==NULL)
{
perror("error");
return NULL;
}
p->next=NULL;
return p;
}
int main(int argc,const char*argv[])
{
//创建套接字文件
int sfd=socket(AF_INET,SOCK_DGRAM,0);
if(sfd==-1)
{
perror("socket error");
return -1;
}
printf("socket success sfd=%d\n",sfd);
struct sockaddr_in sin, cin;
sin.sin_family=AF_INET;
sin.sin_port=htons(SER_PORT);
sin.sin_addr.s_addr=inet_addr(SER_IP);
int len=sizeof(cin);
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
biao *p=fun();
biao *temp=NULL;
temp=p;
xinxi data;
while(1)
{
recvfrom(sfd,&data,sizeof(data),0,(struct sockaddr*)&cin,&len);
if(data.type==0) // 登录
{
p=temp;
sprintf(data.text,"%s上线",data.name);
// 打印客户端登录的信息
printf("%s\n",data.text);
while(p->next!=NULL)
{
p=p->next;
sendto(sfd,&data,sizeof(data),0,(struct sockaddr*)&data,sizeof(data));
}
biao*pnew=(biao*)malloc(sizeof(biao));
pnew->addr=cin;
pnew->next=NULL;
}
else if(data.type==2)// 想说的话
{
p=temp;
while(p->next!=NULL)
{
p=p->next;
sendto(sfd,&data,sizeof(data),0,(struct sockaddr*)&data,sizeof(data));
}
}
else if(data.type==1) //退出
{
puts("quit");
biao*pdel=NULL;
p=temp;
sprintf(data.text,"%s下线",data.name);
while(p->next!=NULL)
{
//先判断当前节点的下一个节点是不是要删除的客户端
if(memcmp(&(p->next->addr),&cin,sizeof(cin))==-1)
{
pdel=p->next;
p->next=pdel->next;
//节点释放
free(pdel);
pdel=NULL;
}
else
{
p=p->next;
sendto(sfd,&data,sizeof(data),0,(struct sockaddr*)&sin,sizeof(data));
}
}
}
}
return 0;
}
客户端
#include <my.h>
#define SER_PORT 8888
#define SER_IP "192.168.125.27"
typedef struct lianbiao
{
struct sockaddr_in addr;
struct lianbiao*next;
}biao;
//客户端信息
typedef struct lian
{
int type;
char name[32];
char text[128];
}xinxi;
biao *fun()
{
biao*p=(biao *)malloc(sizeof(biao));
if(p==NULL)
{
perror("error");
return NULL;
}
p->next=NULL;
return p;
}
int main(int argc,const char*argv[])
{
//创建套接字文件
int sfd=socket(AF_INET,SOCK_DGRAM,0);
if(sfd==-1)
{
perror("socket error");
return -1;
}
printf("socket success sfd=%d\n",sfd);
struct sockaddr_in sin, cin;
sin.sin_family=AF_INET;
sin.sin_port=htons(SER_PORT);
sin.sin_addr.s_addr=inet_addr(SER_IP);
int len=sizeof(cin);
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
biao *p=fun();
biao *temp=NULL;
temp=p;
xinxi data;
while(1)
{
recvfrom(sfd,&data,sizeof(data),0,(struct sockaddr*)&cin,&len);
if(data.type==0) // 登录
{
p=temp;
sprintf(data.text,"%s上线",data.name);
// 打印客户端登录的信息
printf("%s\n",data.text);
while(p->next!=NULL)
{
p=p->next;
sendto(sfd,&data,sizeof(data),0,(struct sockaddr*)&data,sizeof(data));
}
biao*pnew=(biao*)malloc(sizeof(biao));
pnew->addr=cin;
pnew->next=NULL;
}
else if(data.type==2)// 想说的话
{
p=temp;
while(p->next!=NULL)
{
p=p->next;
sendto(sfd,&data,sizeof(data),0,(struct sockaddr*)&data,sizeof(data));
}
}
else if(data.type==1) //退出
{
puts("quit");
biao*pdel=NULL;
p=temp;
sprintf(data.text,"%s下线",data.name);
while(p->next!=NULL)
{
//先判断当前节点的下一个节点是不是要删除的客户端
if(memcmp(&(p->next->addr),&cin,sizeof(cin))==-1)
{
pdel=p->next;
p->next=pdel->next;
//节点释放
free(pdel);
pdel=NULL;
}
else
{
p=p->next;
sendto(sfd,&data,sizeof(data),0,(struct sockaddr*)&sin,sizeof(data));
}
}
}
}
return 0;
}