阻塞接收不到数据的recv() (TCP)



我试图使用C系统调用编写一个简单的服务器,它从未知客户端获取未知的字节流,并根据客户端输入执行特定的操作。例如,客户端将发送一个命令"乘以2 2",服务器将这些数字相乘并返回结果。

为了避免服务器在客户端写入之前读取的错误,我使用MSG_PEEK阻塞recv()调用来等待任何数据。当recv检测到要读取的数据时,我转向非阻塞的recv(),逐个字节读取流。

一切正常,除了客户端不发送数据的情况(即write(socket, ", 0);). 我想知道如何准确地检测到没有发送数据的消息。在这种情况下,recv()永远阻塞。

同样,这篇文章几乎总结了我的问题,但它并没有提出一种检测大小为0的数据包的方法。如果recv()接收到有效载荷大小为0

的有效TCP数据包,它将返回什么值?

当在send/recv级别使用TCP时,您不知道进入流的数据包流量。当您通过TCP流发送非零字节数时,序列号增加字节数。这就是双方如何知道对方在成功交换数据方面的位置。发送具有相同序列号的多个数据包并不意味着客户端做了任何事情(例如您的write(s, "", 0)示例),它只是意味着客户端想要通信一些其他信息(例如,数据流的ACK)。当在流级别操作时,您无法直接看到诸如重传,重复ack或其他异常之类的事情。

你链接的答案也差不多。

一切正常,除了客户端不发送数据的情况(即write(socket, ", 0);).

write(socket, "", 0)根本就不是一个send。它只是一个本地API调用,在网络上不做任何事情。

我想知道如何准确地检测到没有数据的消息被发送。

未发送消息,因此没有什么可检测的。

在这种情况下,recv()永远阻塞。

我同意。

我有一个阻塞recv()调用来等待使用MSG_PEEK的任何数据。当recv检测到要读取的数据时,我转向非阻塞的recv(),逐个字节读取流。

您应该使用select()poll()epoll()来检测何时到达数据,然后调用recv()来读取数据,而不是使用recv(MSG_PEEK)

最新更新