设为首页 加入收藏

TOP

使用epoll实现聊天室功能,同时比较epoll和select的异同(二)
2019-03-18 16:08:50 】 浏览:301
Tags:使用 epoll 实现 聊天室 功能 同时 比较 select 异同
intf(
"client connection from:%s : %d (IP:port),clientfd=%d\n",inet_ntoa(client_address.sin_addr),ntohs(client_address.sin_port),clientfd); //cout<<"which chat room: "<<endl; //cin>>MchatId; char message[BUF_SIZE]; bzero(message,BUF_SIZE); sprintf(message,"welcome %d\n which chat room? ",clientfd); int ret=send(clientfd,message,BUF_SIZE,0); //发送欢迎信息 if(ret<0){ perror("send error"); exit(-1); } //recv(clientfd,buf,BUF_SIZE,0); char Mnums[1]; ret=recv(clientfd,Mnums,sizeof(Mnums),0);//接受用户选择的聊天室组号 if(ret<0){ perror("choose error"); exit(-1); } int MchatId=Mnums[0]-'0'; cout<<"MchatId: "<<MchatId<<endl; MUsers * uu=new MUsers(clientfd); uu->chatId=MchatId; clients_list.push_back(*uu); printf("Add new clientfd=%d to epoll\n",clientfd); printf("Now there are %d clients in the chatroom\n",(int)clients_list.size()); printf("welcome message\n"); addfd(epfd,clientfd,true); }else{ int ret=sendBroadcastmessage(sockfd);//对同一组的用户进行广播 if(ret<0){ perror("sendBroad error"); exit(-1); } } } }

2.clients端

(1)初始化sockaddr_in变量

struct sockaddr_in serverAddr;
serverAddr.sin_family=PF_INET;
serverAddr.sin_port=htons(SERVER_PORT);
serverAddr.sin_addr.s_addr=inet_addr(SERVER_IP);

(2)声明socket,connect

 

    int sock=socket(PF_INET,SOCK_STREAM,0);
    if(sock<0){
        perror("sock error");
        exit(-1);
    }
    if(connect(sock,(struct sockaddr *)&serverAddr,sizeof(serverAddr))<0){
        perror("connect error");
        exit(-1);
  }

 

(3)使用pipe管道,并初始化epoll注册表,并将sock和读管道加入到注册表中。

    int pipe_fd[2];
    if(pipe(pipe_fd)<0){
        perror("pipe error");
        exit(-1);
    }
    int epfd=epoll_create(EPOLL_SIZE);
    if(epfd<0){
        perror("epfd error");
        exit(-1);
    }
    static struct epoll_event events[2];
    addfd(epfd,sock,true);
    addfd(epfd,pipe_fd[0],true);//加入读管道是为了获取子进程通过写管道发送的信息 bool isClientwork=true;
  char message[BUF_SIZE];

(4)子进程负责将标准输入中的数据发送到写管道,父进程通过读管道获得标准输入中的数据,然后发送到客户端处理。同时父进程还要负责接受客户端发来的消息。

    int pid=fork();
    if(pid<0){
        perror("fork error");
        exit(-1);
    }
    else if(pid==0){
        close(pipe_fd[0]);
        printf("Please input 'exit' to exit the chat room\n");
        while(isClientwork){
            bzero(&message,BUF_SIZE);
            fgets(message,BUF_SIZE,stdin);//获取标准输入的数据 if(strncasecmp(message,EXIT,strlen(EXIT))==0){
                isClientwork=false;
            }else{
                if(write(pipe_fd[1],message,strlen(message)-1)<0){//通过写管道发送给父进程
                    perror("fork error");
                    exit(-1);
                }
            }
        }
    }else{
        close(pipe_fd[1]);
        while(isClientwork){
            int epoll_events_count=epoll_wait(epfd,events,2,-1);
            for(int i=0;i<epoll_events_count;++i){
                bzero(&message,BUF_SIZE);
                if(events[i].data.fd==sock){//服务器来的消息 int ret=recv(sock,message,BUF_SIZE,0);//接受来自服务器的信息 if(ret==0){
                        printf("server closed connection: %d\n",sock);
                        close(sock);
                        isClientwork=false;
                    }else{
                        printf("%s\n",message);
                    }
                }else{
                    int ret=read(events[i].data.fd,message,BUF_SIZE);//获得标准输入的信息 if(ret==0) i
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++编程知识:多线程编程总结 下一篇dfs板子题-Hdu1283Vegetables

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目