问题描述
- 使用epoll出现问题,偶然性,有时候有问题,有时候又是正常的。
-
我用一个线程监听,如果有数据可读,就通知另一个线程去读。下面是监听线程的代码。出现的问题就是三次握手后,服务端就自动发送了一个FIN报文,接着客户端发送数据就会收到RSTvoid 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);
}
解决方案
望哪位大神帮我看看。刚接触epoll,用的不对的地方还请指教。谢谢了。已经纠结了几天了
解决方案二:
求大神来看看,新手没有悬赏,只能谢谢了
时间: 2024-12-03 18:29:44