使用epoll出现问题,偶然性,有时候有问题,有时候又是正常的。

我用一个线程监听,如果有数据可读,就通知另一个线程去读。下面是监听线程的代码。出现的问题就是三次握手后,服务端就自动发送了一个FIN报文,接着客户端发送数据就会收到RST

void ListenThread::run()
{
int max_epoll=pconf->value("max_connect","1024").toInt();
short listen_port=pconf->value("listen_port","9000").toShort();
int res;

struct sockaddr_in server_addr;
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(listen_port);
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);

int listen_socket=socket(AF_INET,SOCK_STREAM,0);

// int opts=fcntl(listen_socket,F_GETFL);
// fcntl(listen_socket,F_SETFL,opts|O_NONBLOCK);

res=::bind(listen_socket,(sockaddr *)&server_addr,sizeof(server_addr));
if(res!=0){
    emit listen_error();
    return;
}

res=::listen(listen_socket,max_epoll);
if(res!=0){
    emit listen_error();
    return;
}
emit listen_success();

struct epoll_event ev,events[64];
int epfd=epoll_create(max_epoll);
EpollEventData *eed=new EpollEventData;
eed->fd=listen_socket;
ev.data.ptr=eed;
ev.events=EPOLLIN;
epoll_ctl(epfd,EPOLL_CTL_ADD,listen_socket,&ev);

while(isRun){
    //qDebug()<<"listen......";
    int res=epoll_wait(epfd,events,64,100);
    if(res<0){
        emit listen_error();
    }
    for(int i=0;i<res;i++){
        if(((EpollEventData *)events[i].data.ptr)->fd==listen_socket){//有新的连接请求
            //qDebug()<<"new connection in";
            sockaddr_in con_addr;
            socklen_t addr_len;
            int con_socket=::accept(listen_socket,(sockaddr *)&con_addr,&addr_len);

            int opts=fcntl(con_socket,F_GETFL);
            fcntl(con_socket,F_SETFL,opts|O_NONBLOCK);
            EpollEventData * eed_con=new EpollEventData;
            struct epoll_event ev_con;
            eed_con->fd=con_socket;
            inet_ntop(AF_INET,&con_addr.sin_addr,eed_con->ip,INET_ADDRSTRLEN);
            ev_con.data.ptr=eed_con;
            ev_con.events=EPOLLIN|EPOLLONESHOT|EPOLLET;
            epoll_ctl(epfd,EPOLL_CTL_ADD,con_socket,&ev_con);
            //qDebug()<<"new connection add";
        }
        else if(events[i].events & EPOLLIN){//有socket数据可读
            //qDebug()<<"can read";
            EpollEventData *ed=(EpollEventData *)events[i].data.ptr;
            pthread_mutex_lock(&mutex_socket);
            pSocketList->push_back(ed);
            pthread_cond_signal(&cond_socket);
            pthread_mutex_unlock(&mutex_socket);
            //epoll_ctl(epfd,EPOLL_CTL_DEL,ed->fd,&events[i]);
        }
        else{//差错处理

        }
    }
}
delete eed;
::close(listen_socket);
::close(epfd);

}

图片说明

2个回答

望哪位大神帮我看看。刚接触epoll,用的不对的地方还请指教。谢谢了。已经纠结了几天了

求大神来看看,新手没有悬赏,只能谢谢了

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问