基于epoll的聊天室

服务端

#include<iostream>

#include<stdio.h>

#include<sys/types.h>

#include<sys/socket.h>

#include<netinet/in.h>

#include<arpa/inet.h>

#include<assert.h>

#include<unistd.h>

#include<string.h>

#include<string>

#include<stdlib.h>

#include<fcntl.h>

#include<sys/epoll.h>

#include<errno.h>

using namespace std;

//非阻塞

int setnoblocking(int fd){

    int old_option=fcntl(fd,F_GETFL);

    int new_option=old_option | O_NONBLOCK;

    fcntl(fd,F_SETFL,new_option);

    return old_option;

}

//添加socket至epollfd

void addfd(int epollfd,int fd,bool et){

    epoll_event event;

    event.data.fd=fd;

    event.events=EPOLLIN;

    if(et){

        event.events |=EPOLLET;

    }

    epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&event);

    setnoblocking(fd);

}


 

//et模式

void et(epoll_event*events,int number,int epollfd,int listenfd){

    char buf[10];

    for(int b=0;b<number;b++){

        int sockfd=events[b].data.fd;

        if(sockfd==listenfd){

            struct sockaddr_in clnt_addr;

            socklen_t clntlen=sizeof(clnt_addr);

            int connfd=accept(listenfd,(struct sockaddr*)&clnt_addr,&clntlen);

            addfd(epollfd,connfd,true);

        }

        else if(events[b].events & EPOLLIN){

            while(true){

                memset(buf,'\0',10);

                int ret=recv(sockfd,buf,9,0);

                if(ret<0){

                    if((errno==EAGAIN)||(errno==EWOULDBLOCK)){

                        cout<<"read later"<<endl;

                        break;

                    }

                    close(sockfd);

                    break;

                }

                else if(ret==0){

                    close(sockfd);

                }

                else{

                    cout<<buf<<endl;

                }

            }

        }

    }


 

}

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

    int ret=0;

    struct sockaddr_in serve_adr;

    int clnt_adr_size;

    const char* ip=argv[1];

    const char* port=argv[2];

    memset(&serve_adr,0,sizeof(serve_adr));

    serve_adr.sin_family=AF_INET;

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

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

    int listenfd=socket(PF_INET,SOCK_STREAM,0);

    assert(listenfd>=0);

    ret=bind(listenfd,(struct sockaddr*)&serve_adr,sizeof(serve_adr));

    assert(ret!=-1);

    epoll_event events[1024];

    int epollfd=epoll_create(5);

    assert(epollfd!=-1);

    addfd(epollfd,listenfd,true);

    while(true){

        int ret=epoll_wait(epollfd,events,1024,-1);

        if(ret<0){

            cout<<"epoll failure"<<endl;

            break;

        }

        et(events,ret,epollfd,listenfd);

    }

    close(listenfd);

    return 0;

   

}

客户端

#include<iostream>

#include<stdio.h>

#include<sys/types.h>

#include<sys/socket.h>

#include<netinet/in.h>

#include<arpa/inet.h>

#include<assert.h>

#include<unistd.h>

#include<string.h>

#include<string>

#include<stdlib.h>

#include<fcntl.h>

#include<sys/epoll.h>

#include<string>

using namespace std;

int setnoblocking(int fd){

    int old_option=fcntl(fd,F_GETFL);

    int new_option=old_option | O_NONBLOCK;

    fcntl(fd,F_SETFL,new_option);

    return old_option;

}

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

    int ret=0;

    struct sockaddr_in serve_adr,clnt_adr;

    int clnt_adr_size;

    const char* ip=argv[1];

    const char* port=argv[2];

    memset(&serve_adr,0,sizeof(serve_adr));

    serve_adr.sin_family=AF_INET;

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

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

    int sockfd=socket(PF_INET,SOCK_STREAM,0);

    assert(sockfd>=0);

    if(connect(sockfd,(struct sockaddr*)&serve_adr,sizeof(serve_adr))<0){

        perror("connect failed");

        close(sockfd);

        return -1;

    }

    setnoblocking(sockfd);

    string x;

    cin>>x;

    const char*a=x.data();

    write(sockfd,a,sizeof(a));

    close(sockfd);

    return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值