您的位置:首页 > 其它

基于UDP的简易聊天室(服务器端)

2015-07-26 14:16 369 查看
#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <signal.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#define N 64

#define TYPE_R 1 // register

#define TYPE_B 2 // broadcast

#define TYPE_P 3 // private talk

#define TYPE_U 4 // unregister

#define TYPE_Q 5 // quit

#define TYPE_L 6 // user list

typedef struct sockaddr SA;

typedef struct

{

int type;

char from[16];

char to[16];

char text
;

}MESG;

typedef struct _node_

{

struct sockaddr_in peeraddr;

char name[16];

struct _node_ *next;

}linknode,*linklist;

linklist CreateLinklist()

{

linklist h;

h = (linklist)malloc(sizeof(linknode));

h->next = NULL;

return h;

}

AddUser(int sockfd,struct sockaddr_in peeraddr ,MESG buf ,linklist h)//添加成员

{

linklist p = (linklist)malloc(sizeof(linknode));

p->peeraddr = peeraddr;

strcpy(p->name,buf.from);

p->next = h->next;

h->next = p;

buf.type =TYPE_B;

sprintf(buf.text,"%s is online\n",buf.from);

strcpy(buf.from,"system");

h = h->next;

while(h)

{

sendto(sockfd,&buf,sizeof(buf),0,(SA *)&h->peeraddr,sizeof(peeraddr));

h = h->next;

}

return;

}

void Private(int sockfd,struct sockaddr_in peeraddr ,MESG buf ,linklist h)//私聊

{

h = h->next;

while(h)

{

if(strcmp(h->name,buf.to) == 0)

break;

h = h->next;

}

strcpy(buf.from,h->name);

sendto(sockfd,&buf,sizeof(buf),0,(SA *)&h->peeraddr,sizeof(peeraddr));

}

void Broadcast(int sockfd,struct sockaddr_in peeraddr,MESG buf,linklist h)//群聊,广播

{

h = h->next;

while(h)

{

if(strcmp(buf.from,h->name) == 0)

{

h = h->next;

continue;

}

sendto(sockfd,&buf,sizeof(buf),0,(SA *)&h->peeraddr,sizeof(peeraddr));

h = h->next;

}

return;

}

void DelUser(int sockfd,struct sockaddr_in peeraddr,MESG buf,linklist h)//删除成员

{

linklist p = (linklist)malloc(sizeof(linknode));

p = h;

h = h->next;

while(h)

{

if(strcmp(buf.from,h->name) == 0)

{

h = h->next;

continue;

}

sendto(sockfd,&buf,sizeof(buf),0,(SA *)&h->peeraddr,sizeof(peeraddr));

h = h->next;

}

linklist q = (linklist)malloc(sizeof(linknode));

q = p;

p = p->next;

while(p)

{

if(strcmp(buf.from,p->name) == 0)

{

q->next = p->next;

free(p);

break;

}

q = p;

p = p->next;

}

return;

}

void List(int sockfd,struct sockaddr_in peeraddr,MESG buf,linklist h)//显示所有在线成员

{

h = h->next;

while(h)

{

strcpy(buf.text,h->name);

sendto(sockfd,&buf,sizeof(buf),0,(SA *)&peeraddr,sizeof(peeraddr));

h = h->next;

}

}

int main(int argc,char *argv[])

{

pid_t pid;

int sockfd;

MESG buf;

struct sockaddr_in myaddr,peeraddr;

if (argc < 3)

{

printf("Usage : %s <my_ip> <my_port>\n", argv[0]);

exit(-1);

}

if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)

{

perror("fail to socket");

exit(-1);

}

bzero(&myaddr, sizeof(myaddr));

myaddr.sin_family = PF_INET;

myaddr.sin_port = htons(atoi(argv[2]));

myaddr.sin_addr.s_addr = inet_addr(argv[1]);

if (bind(sockfd, (SA *)&myaddr, sizeof(myaddr)) < 0)

{

perror("fail to bind");

exit(-1);

}

if((pid =fork()) < 0)

{

perror("fail to fork");

exit(-1);

}

else if(pid == 0)

{

linklist h = CreateLinklist();

while(1)

{

socklen_t peerlen = sizeof(peeraddr);

recvfrom(sockfd,&buf,sizeof(buf),0,(SA *)&peeraddr,&peerlen);

switch(buf.type)

{

case TYPE_R:

AddUser(sockfd,peeraddr ,buf,h);

break;

case TYPE_B:

Broadcast(sockfd,peeraddr,buf,h);

break;

case TYPE_P:

Private(sockfd,peeraddr,buf,h);

break;

case TYPE_U:

DelUser(sockfd,peeraddr,buf,h);

break;

case TYPE_L:

List(sockfd,peeraddr,buf,h);

break;

}

}

}

else

{

while(1)

{

printf("<system> ");

fgets(buf.text,N,stdin);

if(strncmp(buf.text,"quit",4) == 0)

{

printf("byebye!\n");

kill(0,SIGKILL);

}

}

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: