服务器
#include "_udp.h"
typedef struct node
{
struct sockaddr_in cin;
struct node* next;
}node_t;
struct MSG
{
char type;
char name[8];
char text[128];
};
node_t* create_node()
{
node_t *p=(node_t*)malloc(sizeof(node_t));
if(NULL==p)
{
printf("创建头结点失败\n");
return NULL;
}
return p;
}
void login(node_t *p,struct sockaddr_in cin,struct MSG msg,int sfd)
{
node_t *q=p->next;
while(q!=NULL)
{
if(sendto(sfd,&msg,sizeof(struct MSG),0,(struct sockaddr*)&(q->cin),sizeof(q->cin))<0)
{
ERRMSG("sendto");
}
q=q->next;
}
node_t *a=create_node();
if(NULL==a)
{
printf("申请节点失败\n");
return;
}
a->cin=cin;
a->next=p->next;
p->next=a;
}
void chat(node_t *p,struct sockaddr_in cin,struct MSG msg,int sfd)
{
node_t *s=p;
node_t *q=p->next;
while(q!=NULL)
{
if(memcmp(&(q->cin),&cin,sizeof(cin))
)
{
if(sendto(sfd,&msg,sizeof(struct MSG),0,(struct sockaddr*)&(q->cin),sizeof(q->cin))<0)
{
ERRMSG("sendto");
}
}
q=q->next;
}
}
void quit(node_t *p,struct sockaddr_in cin,struct MSG msg,int sfd)
{
node_t *q=p->next;
while(q!=NULL)
{
if(memcmp(&(q->cin),&cin,sizeof(cin)))
{
if(sendto(sfd,&msg,sizeof(struct MSG),0,(struct sockaddr*)&(q->cin),sizeof(q->cin))<0)
{
ERRMSG("sendto");
}
q=q->next;
}else
{
node_t *a=q;
q=a->next;
free(a);
a=NULL;
}
}
}
int main(int argc, const char *argv[])
{
if(argc<3)
{
printf("请输入IP PORT\n");
return -1;
}
int sfd=socket(AF_INET,SOCK_DGRAM,0);
if(sfd<0)
{
ERRMSG("socket");
return -1;
}
printf("socket success\n");
struct sockaddr_in sin;
sin.sin_family =AF_INET;
sin.sin_port=htons(atoi(argv[2]));
sin.sin_addr.s_addr=inet_addr(argv[1]);
socklen_t sin_len=sizeof(sin);
if(bind(sfd,(struct sockaddr *)&sin,sin_len)<0)
{
ERRMSG("bind");
return -1;
}
printf("bind success\n");
struct MSG msg;
struct sockaddr_in cin;
socklen_t cin_len =sizeof(cin);
node_t *p=create_node();
if(NULL==p)
{
printf("申请节点失败\n");
return -1;
}
pid_t pid=fork();
if(pid>0)
{
while(1)
{
if(recvfrom(sfd,&msg,sizeof(struct MSG),0,(struct sockaddr*)&cin,&cin_len)<0)
{
ERRMSG("recvfrom");
return -1;
}
printf("%s:%s\n",msg.name,msg.text);
switch(msg.type)
{
case'L':
login(p,cin,msg,sfd);
break;
case'C':
chat(p,cin,msg,sfd);
break;
case'Q':
quit(p,cin,msg,sfd);
break;
}
}
close(sfd);
}else if(pid==0)
{
while(1)
{
msg.type='C';
strcpy(msg.name,"ser");
fgets(msg.text,128,stdin);
msg.text[strlen(msg.text)-1]=0;
if(sendto(sfd,&msg,sizeof(struct MSG),0,(struct sockaddr*)&sin,sin_len)<0)
{
ERRMSG("sendto");
return -1;
}
}
close(sfd);
}else
{
ERRMSG("fork");
}
return 0;
}
客户端#include “_udp.h”
typedef void (*sighandler_t)(int);
struct MSG
{
char type;
char name[8];
char text[128];
};
void handler(int sig)
{
exit(0);
}
int main(int argc, const char *argv[])
{
if(argc<3)
{
printf("请输入IP PORT\n");
return -1;
}
int sfd=socket(AF_INET,SOCK_DGRAM,0);
if(sfd<0)
{
ERRMSG("socket");
return -1;
}
printf("socket success\n");
struct sockaddr_in sin;
memset(&sin,0,sizeof(sin));
sin.sin_family =AF_INET;
sin.sin_port=htons(atoi(argv[2]));
sin.sin_addr.s_addr=inet_addr(argv[1]);
socklen_t sin_len=sizeof(sin);
struct MSG msg;
printf("请输入用户名:");
fgets(msg.name,8,stdin);
msg.name[strlen(msg.name)-1]=0;
msg.type='L';
strcpy(msg.text,"加入群聊");
if(sendto(sfd,&msg,sizeof(struct MSG),0,(struct sockaddr*)&sin,sin_len)<0)
{
ERRMSG("sendto");
return -1;
}
printf("sendto success\n");
pid_t pid=fork();
if(pid>0)
{
sighandler_t s=signal(17,handler);
while(1)
{
if(recvfrom(sfd,&msg,sizeof(struct MSG),0,NULL,NULL)<0)
{
ERRMSG("recvfrom");
}
printf("%s:%s\n",msg.name,msg.text);
}
}else if(pid==0)
{
while(1)
{
fgets(msg.text,128,stdin);
msg.text[strlen(msg.text)-1]=0;
if(strcmp(msg.text,"quit"))
{
msg.type='C';
}else
{
msg.type='Q';
strcpy(msg.text,"退出群聊");
}
if(sendto(sfd,&msg,sizeof(struct MSG),0,(struct sockaddr*)&sin,sin_len)<0)
{
ERRMSG("sendto");
return -1;
}
if(strcmp(msg.text,"退出群聊")==0)
{
break;
}
}
}else
{
ERRMSG("fork");
return -1;
}
return 0;
}
封装头文件_udp.h
#ifndef __uDP_H__
#define __uDP_H__
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/ip.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/select.h>
#include <signal.h>
#define ERRMSG(errmsg) \
do \
{ \
printf("%s--%s(%d):", __FILE__, __func__, __LINE__); \
perror(errmsg); \
\
} while(0)
#endif