2012-07-30 127 views
3

我有兩臺機器運行一個簡單的C TCP服務器,這些服務器是我爲測試目的編寫的,其中1個使用Fedora 16,另一個使用Ubuntu 11.10。我的Fedora機器完美工作,但在Ubuntu機器上,recv()不會阻塞。請記住,這些機器運行的代碼相同。有沒有人看過這個?由於recv()不會阻止

int TcpSocket::ReadFromClient(int socket, char* buf, int len) 
{ 
    char *request = buf; 
    int slen = len; 

    int c = recv(socket, request, slen, 0); 
    while((c > 0) && (request[c-1] != '\n')) 
    { 
     request += c; 
     slen -= c; 
     c = recv(socket, request, slen, 0); 
    } 

    if (c < 0) 
    { 
     return c; 
    } 
    else if(c == 0) 
    { 
     //Sending back an empty string 
     buf[0] = '\0'; 
    } 

    return len-slen; 
} 
+0

是什麼回報? – 2012-07-30 23:52:53

+0

聽起來像您的套接字處於非阻塞模式。 – 2012-07-31 00:10:47

+0

它第一次(實際上是發送數據時)返回1,循環時返回0。爲什麼它會阻塞我的fedora機器? – tier1 2012-07-31 00:44:10

回答

2

它看起來像你的代碼的目的是爲了阻止當'\n'字節到達讀書。如果是這種情況,那麼您需要一次從套接字讀取1個字節,而不是使用整個可用緩衝區大小,尤其是因爲您只是檢查緩衝區的最後一個字節,而不是檢查每個接收到的字節。

您還應該更改循環邏輯,只在一個地方調用recv()而不是兩個地方。當緩衝區耗盡時,您當前的實現將調用recv()與slen=0,這將設置c=0並取消緩衝區中的第一個字節。

試試這個:

int TcpSocket::ReadFromClient(int socket, char* buf, int len) 
{ 
    int slen = len; 
    char ch; 

    while (len > 0) 
    { 
     int ret = recv(socket, &ch, 1, 0); 
     if (ret > 0) 
     { 
      *buf = ch; 
      ++buf; 
      --len; 

      if (ch == '\n') 
       break; 
     } 
     else 
     { 
      if ((ret == 0) || (errno != EAGAIN)) 
       return ret; 

      fd_set readfd; 
      FD_ZERO(&readfd); 
      FD_SET(socket, &readfd); 

      timeval tv; 
      tv.tv_sec = 5; 
      tv.tv_usec = 0; 

      ret = select(socket+1, &readfd, NULL, NULL, &tv); 
      if (ret < 0) 
       return ret; 

      if (ret == 0) 
      { 
       // timeout elapsed while waiting for data 
       // do something if desired... 
      } 
     } 
    } 

    return slen - len; 
} 
+0

可以一次讀取一個字節並停止在換行,或者儘可能多地讀取,並將接收到的數據分爲多行。最後一種方法確實需要爲下一次讀取保存剩餘數據。 – 2012-07-31 05:44:23

+1

使用單獨的緩衝區來接收所有入站數據,然後將該緩衝區按需分割,通常效率更高,並且只要有可能就會首選。逐字節讀取效率較低,但更容易編碼。所以這是個人偏好,效率和代碼複雜度之間的折衷。 – 2012-07-31 19:42:49

+0

@RemyLebeau您的代碼看起來很穩固。但是,在第一次連接後,它仍然在我的Ubuntu機器上以100%運行。開始懷疑我的機器是否有問題。很奇怪。 – tier1 2012-07-31 23:34:57