epoll 实现Chat

服务端

main函数:

int main(int argc,char ** argv){
    
    int sockfd;
    if((sockfd = socket_bulit())==-1){
       printf("built socket error\n");
       return 0;
    }
   
    printf("wait for client connect\n");
   
    do_epoll(sockfd);
}

do_epoll函数:

void do_epoll(int sockfd){
     int epollfd;
     struct epoll_event events[EPOLLEVENTS];
     int ret;
   
     epollfd = epoll_create(FILESIZE);
     add_event(epollfd,sockfd,EPOLLIN);
     
     while(1){
          ret = epoll_wait(epollfd,events,EPOLLEVENTS,-1);
          epoll_handle(epollfd,events,ret,sockfd);
     }
     close(epollfd);
}

epoll_handle函数

void epoll_handle(int epollfd,struct epoll_event *events,int num,int sockfd){
     int i,fd;
     for(i = 0;i<num;i++){
        fd = events[i].data.fd;
 
        if((fd == sockfd) && (events[i].events & EPOLLIN))
            sock_accept(epollfd,sockfd);
        else if(events[i].events & EPOLLIN)
            epoll_read(epollfd,fd);
        else if(events[i].events & EPOLLOUT)
            epoll_write(epollfd,fd);
    }
}

sock_accept函数

void sock_accept(int epollfd,int sockfd){
     int clifd;
     struct sockaddr_in cliaddr;
     socklen_t cliaddrlen = sizeof(struct sockaddr);
     clifd = accept(sockfd,(struct sockaddr*)&cliaddr,&cliaddrlen);
     if(clifd == -1)
        perror("accept error");
     else{
        printf("accept a client from: %s , %d\n",inet_ntoa(cliaddr.sin_addr),cliaddr.sin_port);
        cli[clifd].cliaddr = cliaddr;
        cli[clifd].port = cliaddr.sin_port;
       // setnonblocking(clifd);
        usr[usr_count] = clifd;
        usr_count++;
        add_event(epollfd,clifd,EPOLLIN);
     }
}

epoll_write函数:

void epoll_write(int epollfd,int fd){
     int nwrite;
  
     nwrite = write(fd,cli[fd].write_buf,strlen(cli[fd].write_buf));
     printf("send message to client: %d \n",fd);
     if(nwrite == -1){
        perror("write error:");
        close(fd);
        delete_event(epollfd,fd,EPOLLOUT);
     }
     else
        modify_event(epollfd,fd,EPOLLIN);
}

epoll_read函数:

void epoll_read(int epollfd,int fd){
     int nread;
     nread = read(fd,cli[fd].read_buf,maxline);
     if(nread == -1){
       perror("read error:");
       close(fd);
       delete_event(epollfd,fd,EPOLLIN);
     }
     else if(nread == 0){
       printf("client close\n");
       close(fd);
       delete_event(epollfd,fd,EPOLLIN);
     }
     else{
       printf("from client %d read message : %s\n",fd,cli[fd].read_buf);
       for(int x=0;x<usr_count;x++){
          modify_event(epollfd,usr[x],EPOLLOUT);
         // memset(cli[usr[x]].write_buf,0,sizeof(cli[usr[x]].write_buf));
          strcpy(cli[usr[x]].write_buf,"msg from client  : ");
          cli[usr[x]].write_buf[16] = fd + '0';
          strcat(cli[usr[x]].write_buf, cli[fd].read_buf);
       }
     }
}

客户端

main函数:

int main(int argc,char ** argv){
  
    if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){
      printf("create socket error\n");
      return 0;
    }
    memset(sendline,0,sizeof(sendline));
    memset(recvline,0,sizeof(recvline));
    memset(&servaddr,0,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    inet_pton(AF_INET,IP,&servaddr.sin_addr);

    if(connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0){
      printf("connect error:%s \n",strerror(errno));
      return 0;
    }
     
    do_epoll(sockfd);

    close(sockfd);
    return 0;
}

epoll_write,epoll_read函数:

void epoll_write(int epollfd,int fd,int sockfd){
     int nwrite;
     nwrite = write(fd,sendline,strlen(sendline));
     if(nwrite == -1){
        perror("write error:");
        close(fd);
     }
     else{
         if(fd == STDOUT_FILENO){
             delete_event(epollfd,fd,EPOLLOUT);
         }
         else {
           
           modify_event(epollfd,fd,EPOLLIN);
         }
     }
    memset(sendline,0,sizeof(sendline));
}

void epoll_read(int epollfd,int fd,int sockfd){
     int nread;
     
     if(fd == STDIN_FILENO){
         nread = read(fd,sendline,maxline);
     }

     else{
        nread = read(fd,recvline,maxline);
        printf("%s",recvline);
        memset(recvline,0,sizeof(recvline));
      }

     if(nread == -1){
       perror("read error:");
       close(fd);
     }
     else if(nread == 0){
       printf("server close\n");
       close(fd);
     }
     else{
          
         if(fd == STDIN_FILENO){
           add_event(epollfd,sockfd,EPOLLOUT);
         }
         else {
           delete_event(epollfd,sockfd,EPOLLIN);
           add_event(epollfd,STDOUT_FILENO,EPOLLOUT);
         }
     }
}

epoll_handle,do_epoll函数

void epoll_handle(int epollfd,struct epoll_event *events,int num,int sockfd){
     int i,fd;
     for(i = 0;i<num;i++){
        fd = events[i].data.fd;

        if(events[i].events & EPOLLIN)
                epoll_read(epollfd,fd,sockfd);
        else if(events[i].events & EPOLLOUT)
                epoll_write(epollfd,fd,sockfd);
    }
}

void do_epoll(int sockfd){

     printf("connect to server successful\n");

     int epollfd;
     struct epoll_event events[EPOLLEVENTS];
     int ret;
   
     epollfd = epoll_create(FILESIZE);
     add_event(epollfd,STDIN_FILENO,EPOLLIN);
     setnonblocking(STDIN_FILENO);

     while(1){
          ret = epoll_wait(epollfd,events,EPOLLEVENTS,-1);
          epoll_handle(epollfd,events,ret,sockfd);
     }
     close(epollfd);
}

效果:

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

计算机的小粽子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值