read()在套接字编程中不被阻塞

我有一台服务器每隔5秒向客户端发送一次数据。 我希望客户端阻塞在read(),直到服务器发送一些数据,然后打印它。 我知道read()默认是阻塞的。 我的问题是,我的客户端没有阻止read()。 这很奇怪,这似乎不是一个正常的问题。

我的代码在无限循环中打印出“没有回来”。 我在一台linux机器上编程。 我的代码片段如下。 请指教。

while(1) { n = read(sockfd, recvline, MAXLINE); if ( n > 0) { recvline[n] = 0; if (fputs(recvline, stdout) == EOF) printf("fputs error"); } else if(n == 0) printf("Nothing came back"); else if (n < 0) printf("read error"); } return; 

Solutions Collecting From Web of "read()在套接字编程中不被阻塞"

可能有几个原因,在不同的地方可能有几个例外:

  1. 检查您创建的套接字:

     sockfd=socket(AF_INET,SOCK_STREAM,0); if (sockfd==-1) { perror("Create socket"); } 
  2. 您也可以在使用之前明确启用阻止模式:

     // Set the socket I/O mode: In this case FIONBIO // enables or disables the blocking mode for the // socket based on the numerical value of iMode. // If iMode = 0, blocking is enabled; // If iMode != 0, non-blocking mode is enabled. ioctl(sockfd, FIONBIO, &iMode); 

    或者你可以使用setsockopt如下:

      struct timeval t; t.tv_sec = 0; tv_usec = 0; setsockopt( sockfd, // Socket descriptor SOL_SOCKET, // To manipulate options at the sockets API level SO_RCVTIMEO,// Specify the receiving or sending timeouts const void *(&t), // option values sizeof(t) ); 
  3. 检查读取函数调用(错误的原因)

     n = read(sockfd, recvline, MAXLINE); if(n < 0){ perror("Read Error:"); } 
  4. 另外检查服务器代码

    1. 可能您的服务器发送一些空白(不可打印,空白,输入)章程。 而你不知道这一点。 错误您的服务器代码了。

    2. 或者您的服务器在您的客户端可以读取前终止

  5. 还有一件有趣的事情 ,试着去了解:

    当您在服务器上调用N write() ,不需要在另一端进行N次read()调用。

Greg Hewgill已经写了一个注释:一个EOF(即,通过close()或者shutdown() )的一个明确的停止,通过让recv()返回0来传递给接收端。所以如果你得到0,你知道不会有任何数据,你可以终止阅读循环。

如果您启用了非阻塞,并且没有数据,您将得到-1errno将被设置为EAGAINEWOULDBLOCK

MAXLINE的价值是什么?

如果该值为0,那么它也将返回0。 否则,正如Grijesh Chauhan所说,把它明确地设置为阻止。

或者,你也可以考虑使用recv()来指定阻塞和非阻塞。 它有选项,MSG_WAITALL,它将阻塞,直到所有字节到达。

 n = recv(sockfd, recvline, MAXLINE, MSG_WAITALL);