免费注册 查看新帖 |

Chinaunix

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

[C++] Accept阻塞问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-06-29 11:42 |只看该作者 |倒序浏览
   
不是说Accept在监听socket阻塞的情况下是阻塞的吗,我专门搞了一个线程接收客户端连接,在接收前1个客户端连接的情况下是阻塞的,后来客户端连接超过2个时,accept不停的返回-1,搞得很多客户端都连接不上:Connection refused,奇怪!

struct sockaddr_in sAddr;
    int nListenSocket;
    int nFlag = 1;

    memset(&sAddr, 0, sizeof(sAddr));
    sAddr.sin_family = AF_INET;
    sAddr.sin_port = htons(nPort);
    sAddr.sin_addr.s_addr = inet_addr(sIp);

    nListenSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (nListenSocket < 0)
    {
                nDebugLog(LOG_PRIORITY_ERROR, "New socket failed:%s!",strerror(errno));
        return -1;
    }

    setsockopt(nListenSocket, SOL_SOCKET, SO_REUSEADDR, (void *)&nFlag, sizeof(nFlag));

    if (bind(nListenSocket, (struct sockaddr *)&sAddr, sizeof(sAddr)) < 0)
    {
                nDebugLog(LOG_PRIORITY_ERROR, "Bind socket failed:%s!",strerror(errno));
        close(nListenSocket);
        return -1;
    }
       
        if (listen(nListenSocket, SOCKET_LISTEN_QUEUES) < 0)
        {
                nDebugLog(LOG_PRIORITY_ERROR, "Listen socket failed:%s!",strerror(errno));
        close(nListenSocket);
        return -1;
        }

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
2 [报告]
发表于 2015-06-29 11:54 |只看该作者
代码贴完整点,估计除了第一次,后面调用accept的地方参数不对

论坛徽章:
0
3 [报告]
发表于 2015-06-29 12:28 |只看该作者
回复 2# hellioncu


    void * CheckAndProcessOnSockets(void *arg)
{
        INIT_CONFIG * pInitConfig = (INIT_CONFIG*)arg;
        struct sockaddr_in stSockAddr;
        int clientSocket;
        socklen_t len = sizeof(stSockAddr);
       
        while (1)
        {
                printf("Accept ready...\n");
                clientSocket = accept(pInitConfig->nListenSocket,(struct sockaddr *)&stSockAddr,&len);
                printf("Accept client:%d\n",clientSocket);
                if (clientSocket > 0)
                {
                        if (clientSocket > MAX_SOCKET_NUM)
                        {
                                nDebugLog(LOG_PRIORITY_ERROR, "Too Many Sockets, should start another process!");
                                close(clientSocket);
                                continue;
                        }
                        if (SetNonblock(clientSocket) < 0)
                        {
                                close(clientSocket);
                                continue;
                        }       
                        int nFlag = 1;
                        setsockopt(clientSocket, SOL_SOCKET, SO_KEEPALIVE, (void *)&nFlag, sizeof(nFlag));
                        struct linger l = {1,2};
                        setsockopt(clientSocket, SOL_SOCKET, SO_LINGER, (void *) &l, sizeof(l));
                        setsockopt(clientSocket, IPPROTO_TCP, TCP_NODELAY, &nFlag, sizeof(nFlag));
                       
                        m_sSocketContext[clientSocket].nSocketType = CONN_SOCKET;
                        m_sSocketContext[clientSocket].dwTimeLast = time(0);
                        memset(m_sSocketContext[clientSocket].sIP,0,sizeof(m_sSocketContext[clientSocket].sIP));
                        char* sTemp = inet_ntoa(stSockAddr.sin_addr);
                        memcpy(m_sSocketContext[clientSocket].sIP,sTemp,strlen(sTemp));       
                        m_sSocketContext[clientSocket].nPort = ntohs(stSockAddr.sin_port);
                        m_sSocketContext[clientSocket].ev.data.fd = clientSocket;
                        m_sSocketContext[clientSocket].ev.events = EPOLLIN | EPOLLET;
                        epoll_ctl(m_pIOWorkList[clientSocket%pInitConfig->nIOThreadNum].epoll_fd, EPOLL_CTL_ADD, clientSocket, &(m_sSocketContext[clientSocket].ev));
                }
        }       
}

void AcceptThreadInit()
{
        pthread_t tid;
    pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_create(&tid, &attr, CheckAndProcessOnSockets, &m_cInitConfig);                       
}

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
4 [报告]
发表于 2015-06-29 13:28 |只看该作者
colin8080 发表于 2015-06-29 12:28
回复 2# hellioncu


我猜得没错。
len = sizeof(stSockAddr);放到循环中accept前。

论坛徽章:
0
5 [报告]
发表于 2015-06-29 17:33 |只看该作者
回复 4# hellioncu


    还是那样,不能解决问题,我再看看!

论坛徽章:
1
2015亚冠之迪拜阿赫利
日期:2015-07-01 18:38:38
6 [报告]
发表于 2015-06-29 17:39 |只看该作者
不停返回-1时看一下pInitConfig->nListenSocket的值

论坛徽章:
0
7 [报告]
发表于 2015-06-29 19:48 |只看该作者
pInitConfig->nListenSocket   这个 值的问题, 这个值应该不是你创建的 那个 socket  fd 了

论坛徽章:
0
8 [报告]
发表于 2015-07-01 19:03 |只看该作者
找到原因,但是想不明白:

因为写日志的文件句柄用的没有初始化的指针FILE *fp,结果不但写日志不成功,而且accept也不能接收新的客户端。

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-09-15 06:20:00
9 [报告]
发表于 2015-07-02 17:05 |只看该作者
没看到 你写日志 文件指针和代码,可以附全代码  一起研究下。

论坛徽章:
0
10 [报告]
发表于 2015-07-03 09:06 |只看该作者
回复 9# yangchao1117


    我没有贴url的权限,上百度搜“redis3.0集群代理”,在CSDN上有下载。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP