[英]recv() does not block
我有2台機器運行一個簡單的C TCP服務器,我為測試目的編寫,1用Fedora 16,另一台用Ubuntu 11.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;
}
看起來代碼的意圖是在'\\n'
字節到達時停止讀取。 如果是這種情況,那么您需要一次讀取套接字1個字節而不是使用整個可用緩沖區大小,特別是因為您只檢查緩沖區的最后一個字節而不是檢查接收到的每個字節。
您還應該將循環邏輯更改為僅在一個位置而不是兩個位置調用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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.