使用select等待客户端套接字上的数据

7

有什么想法,为什么当服务器在客户端等待select时写入套接字时,select永远不会完成?

我正在使用C语言在套接字之间进行通信。我的客户端可以成功连接到服务器。

socket_desc=socket(AF_INET,SOCK_STREAM,0);//create the socket descriptor
client->address.sin_addr.s_addr = inet_addr(ipAddress);
client->address.sin_family = AF_INET;
client->address.sin_port = htons(port);

bind(socket_desc,&address,sizeof(address));
connect(socket_desc, &address, sizeof(address));

当我使用recv阻塞并监听数据时,一切工作正常:

int bytesRead = 1;
while(bytesRead){
    int bufsize=1024;        
    char *buffer=malloc(bufsize);
    bytesRead = recv(socket_desc, buffer, bufsize, 0);
    printf("CLIENT RECV: %s", buffer);
}

如果我尝试使用select,它似乎无法读取任何数据。如果我将STDIN添加到fd_set中,我可以强制它从套接字读取数据,但是select似乎无法从socket_desc读取数据时触发...?
int running = 1;
while(running){
    /* wait for something to happen on the socket */
    struct timeval selTimeout;
    selTimeout.tv_sec = 2;       /* timeout (secs.) */
    selTimeout.tv_usec = 0;            /* 0 microseconds */
    fd_set readSet;
    FD_ZERO(&readSet);
    FD_SET(STDIN_FILENO, &readSet);//stdin manually trigger reading
    FD_SET(socket_desc, &readSet);//tcp socket

    int numReady = select(3, &readSet, NULL, NULL, &selTimeout);
            //IT ONLY GETS PAST SELECT ON RETURN FROM THE KEYBOARD
    if(numReady > 0){
        char buffer[100] = {'\0'};
        int bytesRead = read(socket_desc, &buffer, sizeof(buffer));
        printf("bytesRead %i : %s", bytesRead, buffer);
        if(bytesRead == 0){
            running = FALSE;
            printf("Shutdowning client.\n");

        }
    }
1个回答

8

select函数的第一个参数应该是最大套接字id加1。因此,在您的情况下,它应该是:

socket_desc+1

您能尝试一下并查看它是否有效吗?

仅当按键盘上的键时,它才会起作用的原因是因为stdin是0,这将在0-(3-1)范围内进行检查。如果将第一个参数设置为socket_desc + 1,则应检查就绪套接字的0-(socket_desc)范围。


1
另外需要注意的是,在选择多个套接字时,您应该检查套接字ID是否已使用FD_ISSET设置。 - vmpstr
没错,就是这样。我感觉自己很蠢。接下来是FD_ISSET。 - joels

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接