我有两台机器运行一台简单的C TCP服务器,一台是Fedora16,另一台是Ubuntu11.10。我的Fedora机器工作得很好,但在Ubuntu机器上,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;
}发布于 2012-07-31 09:23:50
看起来你的代码的意图是在'\n'字节到达时停止读取。如果是这种情况,那么您需要一次从套接字读取一个字节,而不是使用整个可用缓冲区大小,特别是因为您只检查缓冲区的最后一个字节,而不是检查收到的每个字节。
您还应该将循环逻辑更改为只在一个位置调用recv(),而不是在两个位置。您当前的实现是在缓冲区耗尽时使用slen=0调用recv(),这将设置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;
}https://stackoverflow.com/questions/11731284
复制相似问题