【问题标题】:C select always detects a socket readableC select 总是检测到一个可读的套接字
【发布时间】:2015-10-21 21:57:45
【问题描述】:

我在非常相似的主题上寻找答案,但我没有找到一个好的答案(我认为)。

首先是我的代码:

fd_set readset;
int result;

while(1) {
    FD_ZERO(&readset);
    FD_SET(sock_client, &readset);
    FD_SET(fileno(stdin), &readset);
    result = select(sock_client + 1, &readset, NULL, NULL, NULL);

    if (result > 0) {
        if (FD_ISSET(sock_client, &readset)) {
            memset(buffer, 0, sizeof(buffer));
             read(server_socket, buffer, 5000);
            printf("%s", buffer);
        } 

        if (FD_ISSET(fileno(stdin), &readset)) {
            memset(msg, 0, sizeof(msg));
            read(fileno(stdin), msg, 5000);
            printf("%s", msg);
        }
    }
}

编辑(read() 中的错误已更正):

// socket client
sock_client = do_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

// socket server
server_socket = do_socket(AF_INET, SOCK_STREAM, 0);

// server connexion
do_connect(server_socket, 
    (struct sockaddr *) & addr_sock_host, sizeof(addr_sock_host));

fd_set readset;
int result;

while(1) {
    FD_ZERO(&readset);
    FD_SET(sock_client, &readset);
    FD_SET(fileno(stdin), &readset);
    result = select(sock_client + 1, &readset, NULL, NULL, NULL);

    if (result > 0) {
        if (FD_ISSET(sock_client, &readset)) {
            memset(buffer, 0, sizeof(buffer));
            int size = read(sock_client, buffer, 5000);
            printf("size : %i\n", size);
        } 

        if (FD_ISSET(fileno(stdin), &readset)) {
            memset(msg, 0, sizeof(msg));
            read(fileno(stdin), msg, 5000);
            printf("%s", msg);
        }
    }
}

当我运行它时:

size : -1
size : -1
size : -1
size : -1
size : -1
size : -1
size : -1
size : -1

...无限

编辑结束

实际上,select 总是返回 1,因为 sock_client 总是在 readset 中,而上面没有任何东西可以读取。此外,我的 FD_SET 处于无限循环中。这就是为什么我不明白 sock_client 怎么可能被检测为可读(总是)?

希望您能理解我的问题,如果问题已经被问到,我深表歉意。

谢谢

【问题讨论】:

  • 当 select 说 sock_client 是可读的,当你从中读取时会发生什么?具体来说,read() 调用返回什么?
  • 当你到达 EOF 时,套接字总是可读的,当你读取它时返回0。然后您需要关闭套接字并停止选择它。
  • Select() 可读实际上意味着:“read() 不会阻塞”(在大多数情况下,等等)并且:在 select() 可读之后,你应该执行 read(),并且使用它的返回值。
  • 请在正确的问题中发布确切的代码和新行为(而不是 cmets)。请保留原始代码,以便 cmets 跟踪保持有效。在当前代码下方添加新代码。
  • 那么,read() 返回 -1 是什么意思?为什么不检查errno?

标签: c sockets select


【解决方案1】:

您不需要memset(),,并且您无法说服我从侦听套接字块中读取。这里真正的问题是你是:

  • 从错误的套接字 FD 中读取,并且
  • 完全忽略read()返回的值。

你需要:

  1. 将其存储在一个值中。
  2. 将其与 -1 进行比较,如果是,请立即调用 perror() 或其朋友之一,然后关闭套接字。
  3. 否则,将其与零进行比较,如果是,则关闭套接字。
  4. 否则,使用必须保留的正值作为传入数据的长度?这就是您不需要memset() 的原因。

【讨论】:

    猜你喜欢
    • 2017-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    相关资源
    最近更新 更多