1

出于某种原因,FD_ISSET 总是为 &wfds 返回 true,即使没有要发送的内容。这是代码片段(在客户端和服务器上都相同)。选择说 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;
                        }
                    }
                } 
            }
        }
4

1 回答 1

1

您可能误解了writefds参数如何用于 select()。

writefds当且仅当您有东西要发送时,您应该在调用 select() 之前为您的文件描述符设置标志。

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

于 2013-10-03T22:40:33.733 回答