您应该测试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