代码之家  ›  专栏  ›  技术社区  ›  Andrew Kind

选择c:wfds始终处于打开状态,导致阻塞

  •  1
  • Andrew Kind  · 技术社区  · 11 年前

    由于某种原因,FD_ISSET总是为&wfds,即使没有什么可发送的。这是代码片段(在客户端和服务器上都相同)。客户端和服务器都遇到了相同的问题,select表示wfds已打开。难道它不应该只在我在键盘上键入消息并按enter键时激活吗?

    while (1) {
                //trying select..
                tv.tv_sec = 29;
                tv.tv_usec = 500000;
                FD_ZERO(&rfds);
                FD_ZERO(&wfds);
                FD_SET(new_sockfd, &rfds);
                FD_SET(new_sockfd, &wfds);
    
                n = select(new_sockfd + 1, &rfds, &wfds, NULL, &tv);
    
                if (n > 0) {
                    if (FD_ISSET(new_sockfd, &rfds)) {
    
                        while (1) {
                            if ((num = recv(new_sockfd, buffer, 10240, 0)) == -1) {
                                //fprintf(stderr,"Error in receiving message!!\n");
                                perror("recv");
                                exit(1);
                            } else if (num == 0) {
                                printf("Connection closed\n");
                                return 0;
                            }
                            buffer[num] = '\0';
                            printf("Message received: %s\n", buffer);
                            break;
                        }
                    }
                    //this always returns true on client and host
                    if (FD_ISSET(new_sockfd, &wfds)) {
    
                        while (1) {
                            fgets(buffer, MAXDATASIZE - 1, stdin);
                            if ((send(new_sockfd, buffer, strlen(buffer), 0)) == -1) {
                                fprintf(stderr, "Failure Sending Message\n");
                                close(new_sockfd);
                                exit(1);
                            } else {
                                printf("Message being sent: %s\n", buffer);
                                break;
                            }
                        }
                    } 
                }
            }
    
    1 回复  |  直到 11 年前
        1
  •  1
  •   Laszlo Valko    11 年前

    你可能误解了 writefds 参数适用于select()。

    你应该把旗插进去 写集 在调用select()之前,如果并且仅当您有要发送的内容时。

    然后select()返回,并在 写集 ,当套接字在套接字缓冲区中有足够的空间来接受要发送的数据时。然后检查该标志,并意识到套接字是 可发送 ,并且您还知道您有一些东西要发送,因为最初是您在调用select()之前设置了标志。因此,您可以继续通过套接字发送数据。然后,如果您已经发送了所有数据,并且要发送的缓冲区为空,则保留 写集 下次调用select()时清除。