基于UDP的网络聊天室:
cli.c
#include "people.h"
struct agreeMent
{
char type;
char name[20];
char text[20];
};
struct agreeMent ag;
void * snd(void * arg)
{
int sfd = *(int *)arg;
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
while(1)
{
bzero(ag.text,sizeof(ag.text));
fgets(ag.text,sizeof(ag.text),stdin);
ag.text[strlen(ag.text)-1] = 0;
char buf[128];
int len;
bzero(buf,sizeof(buf));
if(strcasecmp(ag.text,"quit")==0)
{
ag.type = 'Q';
len = sprintf(buf,"%c%s",ag.type,ag.name);
}
else
{
ag.type = 'C';
len = sprintf(buf,"%c%s%s%s%s%s",ag.type,"[",ag.name,"]","说:",ag.text);
}
if(sendto(sfd,buf,len,0,(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("sendto");
return NULL;
}
if(strcasecmp(ag.text,"quit")==0)
{
exit(0);
}
}
pthread_exit(NULL);
}
void * rcv(void * arg)
{
int sfd = *(int *)arg;
struct sockaddr_in cin;
int len = sizeof(cin);
char buf[128];
while(1)
{
bzero(buf,sizeof(buf));
if(recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr *)&cin,&len)<0)
{
ERR_MSG("recvfrom");
return NULL;
}
if(buf[0]=='C')
{
printf("%s\n",buf+1);
}
else
{
printf("%s\n",buf);
}
}
pthread_exit(NULL);
}
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;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
printf("请输入姓名>>>");
fgets(ag.name,sizeof(ag.name),stdin);
ag.name[strlen(ag.name)-1] = 0;
ag.type = 'L';
char buf[128];
int len = sprintf(buf,"%c%s",ag.type,ag.name);
if(sendto(sfd,buf,len,0,(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("sendto");
return -1;
}
pthread_t pth1,pth2;
pthread_create(&pth1,NULL,snd,&sfd);
pthread_create(&pth2,NULL,rcv,&sfd);
pthread_join(pth1,NULL);
pthread_join(pth2,NULL);
return 0;
}
ser.c
#include "people.h"
struct agreeMent
{
char type;
char name[20];
char text[20];
};
struct agreeMent ag;
struct people_head * phead;
void * snd(void * arg)
{
int sfd = *(int *)arg;
struct people_node * pnode = phead->pfirst;
while(1)
{
fgets(ag.text,sizeof(ag.text),stdin);
ag.text[strlen(ag.text)-1]=0;
while(pnode!=NULL)
{
struct sockaddr_in sin;
sin = pnode->data.sin;
if(sendto(sfd,ag.text,sizeof(ag.text),0,(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("sendto");
return NULL;
}
pnode = pnode->pnext;
}
if(pnode==NULL)
{
break;
}
}
pthread_exit(NULL);
}
void * rcv(void * arg)
{
int sfd = *(int *)arg;
struct sockaddr_in cin;
int len = sizeof(cin);
char buf[128];
char str[128];
int res;
while(1)
{
bzero(buf,sizeof(buf));
res = recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr *)&cin,&len);
if(res<0)
{
ERR_MSG("recvfrom");
return NULL;
}
if(buf[0]=='C')
{
struct people_node * pnode = phead->pfirst;
bzero(str,sizeof(str));
int s = sprintf(str,"%s%s%s%d%s%s","[",inet_ntoa(cin.sin_addr),":",ntohs(cin.sin_port),"]",buf+1);
struct people_node * mynode = search_people_node(phead,cin);
struct sockaddr_in sin;
printf("%s\n",str);
while(pnode!=NULL)
{
if(pnode==mynode)
{
pnode = pnode->pnext;
continue;
}
sin = pnode->data.sin;
if(sendto(sfd,buf,s,0,(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("sendto");
return NULL;
}
pnode = pnode->pnext;
}
}
else if (buf[0]=='L')
{
struct people_node * pnode = phead->pfirst;
bzero(str,sizeof(str));
int s = sprintf(str,"%s%s",buf,"已上线");
printf("%s\n",str+1);
struct sockaddr_in sin;
while(pnode!=NULL)
{
sin = pnode->data.sin;
if(sendto(sfd,str,sizeof(str),0,(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("sendto");
return NULL;
}
pnode = pnode->pnext;
}
struct peopleData data;
data.sin = cin;
struct people_node * pfirst = create_people_node(&data);
insert_node_at_tail(phead,pfirst);
}
else if(buf[0]=='Q')
{
struct people_node * mynode = search_people_node(phead,cin);
remove_people_node(phead,mynode);
struct people_node * pnode = phead->pfirst;
bzero(str,sizeof(str));
int s = sprintf(str,"%s%s",buf,"已下线");
printf("%s\n",str+1);
struct sockaddr_in sin;
while(pnode!=NULL)
{
sin = pnode->data.sin;
if(sendto(sfd,str,s,0,(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("sendto");
return NULL;
}
pnode = pnode->pnext;
}
}
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
phead = create_people_head();
int sfd = socket(AF_INET,SOCK_DGRAM,0);
if(sfd<0)
{
ERR_MSG("socket");
return -1;
}
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
if(bind(sfd,(struct sockaddr *)&sin,sizeof(sin))<0)
{
ERR_MSG("bind");
return -1;
}
pthread_t pth1,pth2;
pthread_create(&pth1,NULL,snd,&sfd);
pthread_create(&pth2,NULL,rcv,&sfd);
pthread_join(pth1,NULL);
pthread_join(pth2,NULL);
destroy_people_head(phead);
phead = NULL;
return 0;
}
people.c
#include "people.h"
struct people_head * create_people_head()
{
struct people_head * phead = (struct people_head *)malloc(sizeof(struct people_head));
if(phead==NULL)
{
printf("people_head create failed");
return NULL;
}
memset(phead,0,sizeof(struct people_head));
phead->len = 0;
return phead;
}
int destroy_people_head(struct people_head * phead)
{
struct people_node * pnode = phead->pfirst;
struct people_node * ptemp = NULL;
while(pnode!=NULL)
{
ptemp = pnode->pnext;
free(pnode);
pnode = NULL;
pnode = ptemp;
}
free(phead);
phead = NULL;
return 0;
}
struct people_node * create_people_node(struct peopleData * data)
{
struct people_node * pnode =(struct people_node *)malloc(sizeof(struct people_node *));
if(NULL==pnode)
{
printf("people_node create failed");
return NULL;
}
memset(pnode,0,sizeof(struct people_node));
memcpy(&pnode->data,data,sizeof(struct peopleData));
return pnode;
}
int destroy_people_node(struct people_node * pnode)
{
if(pnode!=NULL)
{
free(pnode);
pnode = NULL;
}
return 0;
}
int insert_node_at_tail(struct people_head * phead,struct people_node * pnode)
{
struct people_node * pfirst = phead->pfirst;
while(pfirst!=NULL)
{
if(pfirst->pnext==NULL)
{
break;
}
pfirst = pfirst->pnext;
}
if(pfirst!=NULL)
{
pfirst->pnext = pnode;
}
else
{
phead->pfirst = pnode;
}
pnode->pnext = NULL;
phead->len++;
return 0;
}
struct people_node * search_people_node(struct people_head * phead,struct sockaddr_in sin)
{
struct people_node * pnode = phead->pfirst;
while(pnode!=NULL)
{
printf("%d\n",pnode->data.sin.sin_port);
if(ntohs(pnode->data.sin.sin_port)==ntohs(sin.sin_port))
{
break;
}
pnode = pnode->pnext;
}
return pnode;
}
struct people_node * get_prev_node(struct people_head * phead,struct people_node * pnode)
{
struct people_node * pprev = phead->pfirst;
if(pprev==NULL)
{
return NULL;
}
else
{
if(pnode==pprev)
{
return NULL;
}
else
{
while(pprev!=NULL&&pprev->pnext!=pnode)
{
pprev = pprev->pnext;
}
return pprev;
}
}
return pprev;
}
int remove_people_node(struct people_head * phead,struct people_node * pnode)
{
struct people_node * pprev = get_prev_node(phead,pnode);
if(pprev!=NULL)
{
pprev->pnext = pnode->pnext;
pnode->pnext = NULL;
destroy_people_node(pnode);
pnode = NULL;
phead->len--;
return 1;
}
else if (pnode==phead->pfirst)
{
phead->pfirst = pnode->pnext;
pnode->pnext = NULL;
destroy_people_node(pnode);
pnode = NULL;
phead->len--;
return 1;
}
return 0;
}
people.h
#ifndef __PEOPLE_H__
#define __PEOPLE_H__
#include
#define ERR_MSG(msg) do{\
printf("%d",__LINE__);\
perror(msg);\
}while(0)
#define IP "192.168.114.153"
#define PORT 8888
struct peopleData
{
struct sockaddr_in sin;
};
struct people_node
{
struct peopleData data;
struct people_node * pnext;
};
struct people_head
{
int len;
struct people_node * pfirst;
};
struct people_head * create_people_head();
int destroy_people_head(struct people_head * phead);
struct people_node * create_people_node(struct peopleData * data);
int destroy_people_node(struct people_node * pnode);
int insert_node_at_tail(struct people_head * phead,struct people_node * pnode);
struct people_node * search_people_node(struct people_head * phead,struct sockaddr_in sin);
int remove_people_node(struct people_head * phead,struct people_node * pnode);
#endif