FD_ISSET始终返回false

时间:2016-05-05 17:24:22

标签: c sockets select

我是C套接字编程的新手,我正在尝试使用select(...)来实现客户端 - 服务器非阻塞应用程序。

当我运行调试服务器代码并尝试连接客户端时,select(...)返回1(如预期的那样)但由于某种原因,FD_ISSET在描述符集中找不到文件描述符ID

我已经花了好几天的时间进行调试,而且我的想法已经不多了。 任何帮助将不胜感激!

void server_listen(int port_number){


    tcpsock_t * server, * client;
    fd_set master_set, working_set;
    int listen_sd;

    int max_sd, rc, desc_ready, bytes, result, close_conn;
    dplist_node_t * reference;




    if (tcp_passive_open(&server,PORT)!=TCP_NO_ERROR) exit(EXIT_FAILURE);
    if (tcp_get_sd(server,&listen_sd)!=TCP_NO_ERROR) exit(EXIT_FAILURE);

    FD_ZERO(&master_set);
    max_sd = listen_sd;
    FD_SET(listen_sd, &master_set);

    do {
        timeout.tv_sec  = 30;
        timeout.tv_usec = 0;

        memcpy(&working_set, &master_set, sizeof(master_set));
        printf("Waiting on select()...\n");
        rc = select(max_sd + 1, &working_set, NULL, NULL, &timeout);

        if (rc < 0)
        {
            perror("  select() failed");
            break;
        }
        if (rc == 0)
        {
            printf("  select() timed out.\n");

        }
        desc_ready = rc;
        for (int i=1; i <= max_sd  &&  desc_ready > 0; ++i)
        {
            if (FD_ISSET(i, &working_set))
            {
                desc_ready -= 1;

                if (i == listen_sd)
                {
                    printf("  Listening socket is readable\n");

                  //do something with the new socket
                }

            }
            else
            {
                printf("  Descriptor %d is readable\n", i);
                close_conn = FALSE;

               //read data from already existing socket connection

            } /* End of existing connection is readable */
        } /* End of if (FD_ISSET(i, &working_set)) */
    }
    while (end_server == FALSE);

}

int tcp_passive_open(tcpsock_t ** sock, int port)
{
    int result;
    struct sockaddr_in addr;

    tcpsock_t * s = (tcpsock_t *) malloc(sizeof(tcpsock_t));
    s->cookie = 0;  
    s->port = -1;
    s->ip_addr = NULL;
    s->sd = -1;

    s->sd = socket(PROTOCOLFAMILY, TYPE, PROTOCOL);

    memset(&addr, 0, sizeof(struct sockaddr_in));
    addr.sin_family = PROTOCOLFAMILY;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(port);
    result = bind(s->sd,(struct sockaddr *)&addr,sizeof(addr));
    result = listen(s->sd,MAX_PENDING);
    s->ip_addr = NULL; 
    s->port = port;
    s->cookie = MAGIC_COOKIE;
    *sock = s;
    return TCP_NO_ERROR;
}

int tcp_get_sd(tcpsock_t * socket, int * sd)
{
  *sd = socket->sd;
  return TCP_NO_ERROR;
}

1 个答案:

答案 0 :(得分:1)

你的for循环从1开始。如果min-height: 100px回到0,你的循环就会失败。

所以,改变:

listen_sd

分为:

for (int i=1; i <= max_sd  &&  desc_ready > 0; ++i)

此外,只使用一个文件描述符,您根本不需要for循环。

<强>更新

由于您已发布for (int i=0; i <= max_sd && desc_ready > 0; ++i) 个功能,我可以进一步发表评论。因为您显示tcp_*PROTOCOLFAMILYTYPE是什么,所以他们是可疑的。

由于您遇到问题,请检查PROTOCOLsocketbind的返回值是否有任何错误。

有关简单工作的客户端/服务器应用程序的示例,请参阅我的答案:executing commands via sockets with popen()