2012-07-30 87 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