为什么选择不告诉我客户想连接?

时间:2016-01-27 09:57:09

标签: linux tcp sockets

我已经创建了一个简单的tcp服务器,我可以使用telnet程序进行测试。

在Windows上运行时,它按预期工作,在linux上运行时,行为很奇怪:

  • telnet客户端了解它们已连接到服务器,
  • 服务器看不到客户端(select始终返回0),
  • 当我终止服务器时,客户端检测到断开连接。

我想我错过了acceptlistenselect中的内容。

我错过了什么?

感谢。

这是节目源:

#include "headers.h"
#define DEFAULT_PORT 24891

/**
 * test_server [ip port]
 */
int main(int argc, char *argv[])
{
    sockaddr_in sin;
    socket_t sock;

    /* listening socket creation */
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == sock)
        { die("socket()"); }        

    /* binding */
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = htonl(INADDR_ANY);
    sin.sin_port = htons(DEFAULT_PORT);
    if (3 == argc)
    {
        sin.sin_addr.s_addr = inet_addr(argv[1]);
        sin.sin_port = htons(strtol(argv[2], NULL, 0));
    }

    if (-1 == bind(sock, (sockaddr*) &sin, sizeof(sin)))
        { die("bind()"); }

    /* Listening */
    if (-1 == listen(sock, SOMAXCONN))
        { die("listen()"); }     

    while (1)
    {
        timeval timeout = { 1, 0 };
        fd_set in_set;

        FD_ZERO(&in_set);
        FD_SET(sock, &in_set);

        // select the set
        int cnt = select(1, &in_set, NULL, NULL, &timeout);

        if (cnt > 0)
        {
            // ask if an event occurs on listening socket
            if (FD_ISSET(sock, &in_set))
            {
                /* a new client wants to connect */
                socket_t csock = accept(sock, NULL, NULL);

                send(csock, "hello\r\n", 7, 0);
                printf("new client!\n");

                close(csock);                
            }
        }     
        else if (cnt < 0)
            { die("select"); }

    }

    /* closing listen socket */
    close(sock);
    printf("socket closed\n");

    return 0;
}

1 个答案:

答案 0 :(得分:2)

您只是错误地选择了选择。第一个参数需要是fdset中编号最高的fd加一。见手册页:

int select(int nfds, fd_set *readfds, fd_set *writefds,
           fd_set *exceptfds, struct timeval *timeout);
....

nfds is the highest-numbered file descriptor in any of the three sets,  plus 1.

代码可能有效,也可能没有,取决于“socket()”返回的fd。

在你的情况下,“nfds”的值必须是“sock + 1”,通常你需要在多个fd上进行选择时跟踪编号最高的fd。