自我建设外贸网站,com和cn和net域名区别,建网站 需要签署协议,seo如何优化的基于tcp和epoll在线聊天室 说明服务端代码 说明 服务端#xff1a;实现了验证用户是否已经存在#xff08;支持最大64用户连接#xff09;支持广播用户进入退出聊天室以及用户聊天内容。 这里只提供里服务端代码#xff0c;如果想要看客户端代码点击这里。
服务端代码… 基于tcp和epoll在线聊天室 说明服务端代码 说明 服务端实现了验证用户是否已经存在支持最大64用户连接支持广播用户进入退出聊天室以及用户聊天内容。 这里只提供里服务端代码如果想要看客户端代码点击这里。
服务端代码
#include stdio.h
#include stdlib.h
#include sys/types.h
#include sys/stat.h
#include sys/wait.h
#include string.h
#include fcntl.h
#include unistd.h
#include errno.h
#includesys/types.h
#includesys/socket.h
#include arpa/inet.h
#include time.h
#include sys/epoll.htypedef struct sockaddr SA;
typedef struct sockaddr_in SIN;
#define MAXBACKLOG 100int Socket(int domain,int type,int protocol);
int Bind(int sockfd,struct sockaddr * my_addr,int addrlen);
int Listen(int s,int backlog);
int Accept(int s,struct sockaddr * addr,int * addrlen);
int is_exist(char * username);
void broadcast(char *r,char *n);char Userlist[64][20] {0};
int Userfdlist[64] {0};//./app 192.168.5.166 8888
int main(int argc,char *argv[])
{ int opt 1;//建立监听套接字int socketfd Socket(AF_INET,SOCK_STREAM,0);//需要进行重用地址及其端口号setsockopt(socketfd,SOL_SOCKET,SO_REUSEADDR,opt,sizeof(opt));//绑定信息编写服务器信息SIN serverinfo;serverinfo.sin_family AF_INET;serverinfo.sin_port htons(atoi(argv[2])); serverinfo.sin_addr.s_addr inet_addr(argv[1]);int addrlen sizeof(SIN);Bind(socketfd,(SA*)serverinfo,addrlen);//监听Listen(socketfd,MAXBACKLOG);//epoll创建根节点int epollfd epoll_create(1024);//添加socketfd文件描述符至内核 红黑树struct epoll_event event;event.events EPOLLIN; //事件成员event.data.fd socketfd; //数据epoll_ctl(epollfd,EPOLL_CTL_ADD,socketfd, event);//读写while(1){struct epoll_event events[10];int count epoll_wait(epollfd,events,10,-1);for(int i 0; i count;i){if(events[i].events EPOLLIN){if(events[i].data.fd socketfd){//wait client connectSIN clientinfo;struct epoll_event event;int clientaddrlen sizeof(SA);int newfd Accept(socketfd,(SA*)clientinfo,clientaddrlen);printf(客户端地址:%s 端口号:%d\n,inet_ntoa(clientinfo.sin_addr),ntohs(clientinfo.sin_port));//read usernamechar namebuff[20];read(newfd,namebuff,sizeof(namebuff));if(is_exist(namebuff)){write(newfd,已存在,sizeof(已存在));close(newfd);}else{//put newfd into Red-Black Treeevent.events EPOLLIN; //事件成员event.data.fd newfd; //数据epoll_ctl(epollfd,EPOLL_CTL_ADD,newfd, event);write(newfd,登录成功,sizeof(登录成功)); //save userfd usernamefor(int j0;j64;j)if(strlen(Userlist[j])0){Userfdlist[j]event.data.fd;strcpy(Userlist[j],namebuff);break;} char r[50];sprintf(r,%s %s,namebuff,进入聊天室);printf(%s\n,r);broadcast(r,namebuff);}}else{//readchar readbuff[512] {0};int len read(events[i].data.fd,readbuff,sizeof(readbuff));//get name and poschar namebuff[20] {0};int key 0;for(int i0;i10;i)if(strstr(readbuff,Userlist[i])){strcpy(namebuff,Userlist[i]);keyi;break;}if(len 0 strlen(readbuff)!0){printf(%s\n,readbuff);broadcast(readbuff,namebuff);if(strstr(readbuff,退出)){strcpy(Userlist[key],\0);Userfdlist[key] 0;epoll_ctl(epollfd,EPOLL_CTL_DEL,events[i].data.fd,NULL);close(events[i].data.fd);}}else if(len 0){epoll_ctl(epollfd,EPOLL_CTL_DEL,events[i].data.fd,NULL);close(events[i].data.fd);}}}}}//关闭close(socketfd);return 0;
}
int is_exist(char * username)
{for(int i 0 ; i 10; i)if(strcmp(username,Userlist[i]) 0)return 1;return 0;
}
void broadcast(char *r,char *n)
{for(int i0 ; i64 ;i)//if it is a user and not himselfif(strcmp(Userlist[i],n)!0 strlen(Userlist[i])!0)write(Userfdlist[i],r,strlen(r));
}
int Socket(int domain,int type,int protocol)
{int socketFd socket(domain,type,protocol);if(socketFd -1){perror(socket);exit(1);}return socketFd;
}
int Bind(int sockfd,struct sockaddr * my_addr,int addrlen)
{int val bind(sockfd,my_addr,addrlen);if(val){perror(bind);exit(1);}return 0;
}
int Listen(int s,int backlog)
{int val listen(s,backlog);if(val -1){perror(listen);exit(1);}return val;
}
int Accept(int s,struct sockaddr * addr,int * addrlen)
{int NEWfd accept(s,addr,addrlen);if(NEWfd -1){perror(listen);exit(1);}return NEWfd;
}