您應該測試recv
和break
你的循環的回報,如果它是EAGAIN
或EWOULDBLOCK
:
EAGAIN或EWOULDBLOCK
的插槽上都標非阻塞並且接收操作將會阻塞,或者接收超時已經設置,並且在數據收到之前超時已過期
struct timeval tv = {5, 0};
setsockopt(cli_socket, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *)&tv, sizeof(struct timeval));
while((cut = buffer.find("\r\n")) == -1)
{
int numBytes = recv(cli_socket, tmpBuffer, 100, 0));
/// Edit: recv does not return EAGAIN else, it return -1 on error.
/// and in case of timeout, errno is set to EAGAIN or EWOULDBLOCK
if (numBytes <= 0)
{
// nothing received from client in last 5 seconds
break;
}
buffer.append(tmpBuffer, numBytes);
}
您還可以使用select
函數,而不是那麼複雜的使用方法:
while((cut = buffer.find("\r\n")) == -1)
{
timeval timeout = { 5, 0 };
fd_set in_set;
FD_ZERO(&in_set);
FD_SET(cli_socket, &in_set);
// select the set
int cnt = select(cli_socket + 1, &in_set, NULL, NULL, &timeout);
if (FD_ISSET(cli_socket, &in_set))
{
int numBytes = recv(cli_socket, tmpBuffer, 100, 0));
if (numBytes <= 0)
{
// nothing received from client
break;
}
buffer.append(tmpBuffer, numBytes);
}
else
{
// nothing received from client in last 5 seconds
break;
}
}
你'setsockopt'通話似乎好於我,這對我的作品。你看到了什麼行爲,它與你期望的有什麼不同?我注意到你不檢查'recv()'的返回值,這確實讓我懷疑你期望如果超時會發生什麼。 – Dolda2000
我想關閉連接,如果超時 – lllook