免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6439 | 回复: 2
打印 上一主题 下一主题

[C++] 求助:accept出现11错误,accept: Resource temporarily unavailable [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-02-18 22:50 |只看该作者 |倒序浏览
本帖最后由 w1964332 于 2014-02-18 22:50 编辑

代码如下:
#include <iostream>
#include <sys/socket.h>
#include <sys/unistd.h>
#include <sys/epoll.h>
#include <errno.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
using namespace std;

#define unsigned short ushort;
#define unix_error(s)        do{ perror(s);printf("errno:%d\n",errno);} while(0)

//#define void *(*handle)(void *)

/*
typedef struct _fd_event{
        int fd;        //client fd
        handle func;        //callback function
        int type; //event type , read ,wrte
       
}fd_event;*/

bool set_nonblock(int fd){
        int opt;
        opt = fcntl(fd, F_GETFL);
        if(opt < 0){
                unix_error("get file status");
                return false;
        }
        opt = fcntl(fd, F_SETFL, opt | O_NONBLOCK);
        if(opt <0){
                unix_error("set file status");
                return false;
        }
        return true;
}

class Epoll_server{
public:       
        Epoll_server();
        Epoll_server(const char *ip, const ushort uport, int timeout_, int max_event_);
        void run();
        static void* process_connect(void *p);
        void process_event(struct epoll_event *event);
        void add_event();
        int s_fd; //server fd
        set<int> client_set;
        int nfds;        //epoll fd
private:
        char ipaddr[20]; //server ip
        ushort port;        //server port
        int timeout;
        int max_event;
        char buf[1000];
};

Epoll_server::Epoll_server(){

}

Epoll_server::Epoll_server(const char *ip, const ushort port_, int timeout_, int max_event_){
        strncpy(ipaddr, ip, 20);
        port = port_;
        timeout = timeout_;
        max_event = max_event_;
        memset(buf, 0, 1000);
}

void Epoll_server::run(){
        nfds = epoll_create(1);
        s_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
        if(s_fd < 0) {unix_error("socket");}
        /*
        struct sockaddr_in addr_in;
        bzero(&addr_in, sizeof(struct sockaddr));
        addr_in.sin_family = AF_INET;
        struct in_addr addr;
        addr_in.sin_addr.s_addr = inet_addr(ipaddr);

        addr_in.sin_port = htons(port);*/
        sockaddr_in listen_addr;  
listen_addr.sin_family=AF_INET;  
listen_addr.sin_port=htons ( port );  
listen_addr.sin_addr.s_addr=htonl(INADDR_ANY);  
//listen_addr.sin_addr.s_addr=inet_addr(ipaddr);




        socklen_t sock_size = sizeof(struct sockaddr);
        int reuse = 1; //support port to reuse
//        setsockopt(s_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
        if( -1 == bind(s_fd, (sockaddr *)&listen_addr, sizeof(listen_addr))){
                unix_error("bind");
                exit(1);
        }
        if(-1 == listen(s_fd, 20)){
                unix_error("listen");
                exit(1);
        }
        pthread_t pthid;
        pthread_create(&pthid, NULL, process_connect, this);
        struct epoll_event events[max_event];
        int n = 0;
        while(1){
                printf("wait\n");
                n = epoll_wait(nfds, events, max_event, timeout);
                if(n == 0 ) continue;
                for(int i = 0 ; i < n; i++){
                        process_event(events+i);
                }
        }
}

void *Epoll_server::process_connect(void *p){
        Epoll_server *p_epoll = (Epoll_server *)p;
        int fd = p_epoll->s_fd;
        int clientfd;
        struct sockaddr addr;
        socklen_t len;
        struct epoll_event event;
        while(1){
                memset(&addr , 0, sizeof(sizeof(struct sockaddr)));
                if(-1 == (clientfd = accept(fd, &addr, &len))){
                        unix_error("accept");
                        continue;
                }
                if(false == set_nonblock(clientfd)) continue;
                p_epoll->client_set.insert(clientfd);
        //        event.events = EPOLLIN || EPOLLET;
                event.events = EPOLLIN;
                event.data.fd = clientfd;
                epoll_ctl(p_epoll->nfds, EPOLL_CTL_ADD, clientfd, &event);
        }       
}

void Epoll_server::process_event(struct epoll_event *pevent){
        if(pevent->events & EPOLLIN){
                recv(pevent->data.fd, buf, 1000, 0);       
                pevent->events = EPOLLOUT;
                epoll_ctl(nfds, EPOLL_CTL_MOD, pevent->data.fd,pevent);
        }else if(pevent->events & EPOLLOUT){
                send(pevent->data.fd, "hello", 5, 0);
                pevent->events = EPOLLIN;
                epoll_ctl(nfds, EPOLL_CTL_MOD, pevent->data.fd, pevent);
        }else{
                close(pevent->data.fd);
                epoll_ctl(nfds, EPOLL_CTL_DEL,pevent->data.fd,  NULL);
        }
}

void Epoll_server::add_event(){
       
}

int main(int argc, char **argv){
        Epoll_server server("192.168.1.1", 10001, 1000, 20);
        server.run();
        return 0;
}

大神们能帮忙分析下问题吗?

论坛徽章:
4
双子座
日期:2014-08-28 10:08:002015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:58:112015年亚洲杯之阿联酋
日期:2015-03-13 03:25:15
2 [报告]
发表于 2014-02-19 09:12 |只看该作者
1.你这个程序一般不这样写,一般是主线程accept,子线程处理各种事件
2.你先把socket不设置非阻塞试试  看看还有没有这个错误

论坛徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
3 [报告]
发表于 2014-02-19 10:09 |只看该作者
本帖最后由 gaojl0728 于 2014-02-19 10:17 编辑

查了下glibc,"Resource temporarily unavailable“ 是说返回错误码为EAGAIN或者EWOULDBLOCK, 看man文档就说的很清楚:

       EAGAIN or EWOULDBLOCK
              The  socket  is  marked  non-blocking  and  no  connections are present to be accepted.  POSIX.1-2001 allows either error to be returned for this case, and does not require these constants to have the same value, so a portable application should check for both possibilities.

你的代码报这个错误没问题,只不过accept一直在空循环白白浪费了CPU时间。
你的代码应该检查errono是不是EAGAIN,EWOULDBLOCK如果是,忽略掉这个错误。
设置为阻塞模式就不会有这个问题,一般accept也不需要非阻塞模式。

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP