david_6666 2015-09-22 13:40 采纳率: 0%
浏览 1687

使用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条回答 默认 最新

  • david_6666 2015-09-22 13:42
    关注

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

    评论

报告相同问题?

悬赏问题

  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大