服务器:
typedef struct msg
{
char type; //消息类型
char name[N];//客户名字
char text[N];//正文
}MSG;
typedef struct node
{
struct sockaddr_in adip;//存客户IP
struct node next;
}listnode;
listnode * linklist_t(void)
{
listnode h =(listnode*)malloc(sizeof(listnode));
h->next = NULL;
return h;
}
void long_t(int sockfd,MSG msg,listnode h,struct sockaddr_in adip_t,socklen_t addrlen)
{
char l[N]={0};
sprintf (l,"%s long",msg.name);
strcpy(msg.text,l);
listnodep =h->next;
while (p != NULL)
{
sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr )&(p->adip),addrlen);
p= p->next;
}
p=(listnode)malloc(sizeof(listnode));
p->adip = adip_t;
p->next=h->next;
h->next=p;
}
void chat_t(listnode h,MSG msg, struct sockaddr_in adip_t ,int sockfd,socklen_t addrlen)
{
char l[N]={0};
listnodep =h->next;
sprintf (l,"%s txet: %s",msg.name,msg.text);
strcpy(msg.text,l);
while (p != NULL)
{
if(memcmp(&adip_t,&(p->adip),sizeof(adip_t)) != 0)
{
sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr *)&(p->adip),addrlen);
}
p= p->next;
}
}
void quit_t(int sockfd,listnode * h,MSG msg,struct sockaddr_in adip_t,socklen_t addrlen)
{
char l[N]={0};
sprintf (l,"%s quit",msg.name);
strcpy(msg.text,l);
listnode*p =h->next;
while (p != NULL)
{
if (memcmp(&adip_t,&(p->adip),sizeof(adip_t)) ==0 )
{
h->next = p->next;
free§;
}
if (h->next ==NULL)
{
memset(&msg,0,sizeof(msg));
break;
}
sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr *)&(p->adip),addrlen);
p= p->next;
}
}
int main(int argc, char argv[])
{
int sockfd,ret,pid;
struct sockaddr_in sockaddr, client;
MSG msg;
memset(&msg,0,sizeof(msg));
if (argc != 3)
{
printf (“请带参数”);
exit(-1);
}
socklen_t addrlen = sizeof(client);
sockfd = socket(AF_INET,SOCK_DGRAM,0);
memset(&sockaddr,0,sizeof(sockaddr));
sockaddr.sin_family=AF_INET;
sockaddr.sin_port = htons(atoi(argv[2]));
sockaddr.sin_addr.s_addr = inet_addr(argv[1]);
ret = bind (sockfd,(struct sockaddr)&sockaddr,sizeof(sockaddr));
if (ret < 0)
{
perror(“bind”);
exit(-1);
}
pid = fork();
if (pid == 0)//写消息
{
strcpy(msg.name,“服务器”);
msg.type=‘B’;
while (1)
{
fgets(msg.text,N,stdin) ;
msg.text[strlen(msg.text)-1]=0;
sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&sockaddr,addrlen);//向父进程发
}
}
else if (pid < 0 )
{
perror("fork");
exit(-1);
}
else //接消息
{
listnode* H=linklist_t();//建链表
while (1)
{
recvfrom(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&client,&addrlen);
printf ("%c\n%s %s\n ",msg.type,msg.name,msg.text);
switch (msg.type)
{
case 'L':
long_t(sockfd,msg,H,client,addrlen); //插链表
break;
case 'B':
chat_t(H,msg,client,sockfd,addrlen);//正文
break;
case 'Q':
quit_t(sockfd,H,msg,client,addrlen);//删链表
break;
}
}
}
return 0;
}
客户端 :
struct sockaddr_in {
__kernel_sa_family_t sin_family; /* Address family / 2字节
__be16 sin_port; / Port number / 2字节
struct in_addr sin_addr; / Internet address */ 4字节
char sin_zero[8]; // 8 bytes unused,作为填充
};
struct in_addr
{
in_addr_t s_addr; // u32 network address
};
#endif
typedef struct msg
{
char type; //消息类型
char name[N];//客户名字
char text[N];//正文
}MSG;
int main(int argc, char *argv[])
{
int sockfd,ret,pid;
struct sockaddr_in sockaddr, client;
MSG msg;
memset(&msg,0,sizeof(msg));
if (argc != 3)
{
printf (“请带参数”);
exit(-1);
}
socklen_t addrlen = sizeof(client);
sockfd = socket(AF_INET,SOCK_DGRAM,0);
memset(&sockaddr,0,sizeof(sockaddr));
sockaddr.sin_family=AF_INET;
sockaddr.sin_port = htons(atoi(argv[2]));
sockaddr.sin_addr.s_addr = inet_addr(argv[1]);
if (ret < 0)
{
perror("bind");
exit(-1);
}
printf ("name:");
fgets(msg.name,N,stdin);
msg.name[strlen(msg.name)-1]=0;
msg.type='L';
sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&sockaddr,addrlen);
pid = fork();
if (pid == 0)//写消息
{
while(1)
{
fgets(msg.text,N,stdin);
msg.text[strlen(msg.text)-1]=0;
if (strncmp(msg.text,"quit",4)==0)
{
msg.type='Q';
sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&sockaddr,addrlen);
memset(&msg,0,sizeof(msg));
kill(getppid(),2);
exit(0);
}
else
{
msg.type = 'B';
sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&sockaddr,addrlen);
}
}
}
else if (pid < 0 )
{
perror("fork");
exit(-1);
}
else //接消息
{
while (1)
{
recvfrom(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&client,&addrlen);
printf ("%s\n",msg.text);
}
}
return 0;
}