gpt4 book ai didi

c - 为 socket recv TCP 设置超时

转载 作者:太空宇宙 更新时间:2023-11-04 01:54:30 25 4
gpt4 key购买 nike

我找到了一些关于如何操作的提示,但我不明白如何使用 setsockopt。我有一个无限循环调用 recv,如果客户端在 5 秒内没有发送任何内容,我想超时并 close(cli_socket)

如果客户端只发送整个预期消息的一部分,我想重置计时器并再给他 5 秒。

目前我有这个:

while((cut = buffer.find("\r\n")) == -1)
{
struct timeval tv;
tv.tv_sec = 5;
setsockopt(cli_socket, SOL_SOCKET, SO_RCVTIMEO,(struct timeval *)&tv,sizeof(struct timeval));
recv(cli_socket, tmpBuffer, 100, 0);
buffer += tmpBuffer;
memset(tmpBuffer, 0, 100);
}

最佳答案

如果循环是EAGAINEWOULDBLOCK,您应该测试recvbreak 的返回:

EAGAIN or EWOULDBLOCK
The socket is marked nonblocking and the receive operation would block, or a receive timeout had been set and the timeout expired before data was received

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;
}
}

关于c - 为 socket recv TCP 设置超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36893807/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com