簡體   English   中英

read()在套接字編程中沒有阻塞

[英]read() is not blocking in socket programming

我有一台服務器,每隔5秒就會向客戶端發送一次數據。 我希望客戶端阻止read()直到服務器發送一些數據然后打印它。 我知道read()默認是阻塞的。 我的問題是我的客戶端沒有阻塞read()。 這很奇怪,這似乎不是一個正常的問題。

我的代碼在無限循環中打印“Nothing come back”。 我在linux機器上,用c編程。 我的代碼片段如下。 請指教。

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; 

可能有幾個原因,在不同的地方有幾個例外:

  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,你知道沒有任何數據,你可以終止讀取循環。

如果您啟用了非阻塞且沒有數據,則將獲得-1並將errno設置為EAGAINEWOULDBLOCK

MAXLINE的價值是什么?

如果值為0,則它​​也將返回0。 否則,正如Grijesh Chauhan所提到的那樣,將其明確地設置為阻止。

或者,您也可以考慮使用recv(),其中可以指定阻塞和非阻塞。 它有選項MSG_WAITALL,它將阻塞所有字節到達。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM