gpt4 book ai didi

c - 是否可以循环接收/读取以从套接字读取所有数据

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

我正在构建一个基于 TCP 的多客户端<->服务器消息传递应用程序。我使用 epoll 创建了一个非阻塞服务器来多路复用 linux 文件描述符。
当 fd 接收数据时,我将 read()/or/recv() 读入 buf。我知道我需要在传输开始时指定数据长度*,或者在传输结束时使用定界符**来分隔消息。

*使用数据长度:

char *buffer_ptr = buffer;
do {
switch (recvd_bytes = recv(new_socket, buffer_ptr, rem_bytes, 0)) {
case -1: return SOCKET_ERR;
case 0: return CLOSE_SOCKET;
default: break;
}
buffer_ptr += recvd_bytes;
rem_bytes -= recvd_bytes;
} while (rem_bytes != 0);

**使用分隔符:

void get_all_buf(int sock, std::string & inStr)
{
int n = 1, total = 0, found = 0;
char c;
char temp[1024*1024];
// Keep reading up to a '\n'
while (!found) {
n = recv(sock, &temp[total], sizeof(temp) - total - 1, 0);
if (n == -1) {
/* Error, check 'errno' for more details */
break;
}
total += n;
temp[total] = '\0';
found = (strchr(temp, '\n') != 0);
}
inStr = temp;
}

我的问题:是否可以循环 recv() 直到满足其中一个条件?如果客户端发送虚假的消息长度或没有分隔符或丢包怎么办?我不会永远在我的程序中循环 recv() 吗?

最佳答案

Is it OK to loop over recv() until one of those conditions is met?

可能不会,至少对于生产质量代码而言不会。正如您所建议的那样,在您收到完整消息之前循环的问题在于它会让您的线程任由客户摆布 - 如果客户决定只发送部分消息然后等待很长时间(甚至永远) 而不发送最后一部分,那么你的线程将被无限期地阻塞(或循环)并且无法用于任何其他目的——通常不是你想要的。

What if a client sends a bogus message length

那么你就有麻烦了(尽管如果你选择了最大消息大小,你可以检测到明显大于该大小的虚假消息长度,并通过例如强行关闭连接来保护自己)

or there is packet loss?

如果数据包丢失量相当小,TCP 层将自动重新传输数据,因此您的程序不会注意到差异(除了消息正式“到达”的时间比其他情况晚一点) .如果真的有严重的数据包丢失(例如有人将以太网电缆从墙上拔出 5 分钟),则消息的其余部分可能会延迟几分钟或更长时间(直到连接恢复,或 TCP 层放弃并关闭TCP 连接),将您的线程困在循环中。

那么什么是解决这个难题的工业级、防恶意客户端和糟糕网络的解决方案,以便您的服务器即使在特定客户端不正常时也能保持对其他客户端的响应?

答案是这样的:不要依赖于一次收到全部消息。相反,您需要为每个客户端设置一个简单的状态机,这样您就可以recv() 从该客户端的 TCP 套接字发送给您尽可能多(或尽可能少)的字节在任何特定时间,将这些字节保存到与该客户端关联的本地(每个客户端)缓冲区,然后返回到您的正常事件循环,即使您尚未收到整个消息。仔细跟踪您当前从每个客户端收到的有效数据字节数,并在每次 recv() 调用返回后,检查关联的每个客户端传入数据缓冲区是否包含整个消息,或者不是——如果是,解析消息,对其进行操作,然后将其从缓冲区中删除。起泡、冲洗并重复。

关于c - 是否可以循环接收/读取以从套接字读取所有数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53073545/

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