我正在尝试使用C系统调用编写一个简单的服务器,该系统调用从未知客户端获取未知字节流,并根据客户端输入执行特定操作。例如,客户端将发送命令“multiply 2 2”,服务器将乘以数字并返回结果。
为了避免服务器在客户端写入之前读取错误,我有一个阻塞的recv()调用来等待使用MSG_PEEK的任何数据。当recv检测到要读取的数据时,我会移动到非阻塞的recv(),它逐字节地读取流。
除了在客户端不发送数据的角落情况(即write(socket,“”,0);)之外,一切正常。我想知道我是如何检测到没有数据的消息被发送的。在这种情况下,recv()永远阻止。
此外,这篇文章几乎总结了我的问题,但它没有提出一种方法来检测0大小的数据包。 What value will recv() return if it receives a valid TCP packet with payload sized 0
答案 0 :(得分:1)
在send
/ recv
级别使用TCP时,您不了解制作流的数据包流量。当您通过TCP流发送非零字节数时,序列号会增加字节数。这就是双方如何在成功交换数据方面知道对方的位置。发送具有相同序列号的多个数据包并不意味着客户端做了任何事情(例如您的write(s, "", 0)
示例),它只是意味着客户端想要传达其他一些信息(例如,ACK数据以其他方式流动)。在流级别操作时,您无法直接查看重新传输,重复的ACK或其他异常情况。
你联系的答案大致相同。
答案 1 :(得分:0)
除了在客户端不发送数据的角落情况(即写入(套接字,“”,0);)之外,一切正常。
write(socket, "", 0)
首先不是发送。它只是一个本地API调用,在网络上什么都不做。
我想知道我究竟会检测到没有数据的消息会被发送。
未发送消息,因此无需检测。
在这种情况下,recv()永远阻止。
我同意。
答案 2 :(得分:-1)
我有一个阻塞的recv()调用来等待使用MSG_PEEK的任何数据。当recv检测到要读取的数据时,我会移动到非阻塞的recv(),它逐字节地读取流。
您应该使用recv(MSG_PEEK)
,select()
或poll()
来检测数据何时到达,然后调用epoll()
来读取它,而不是使用recv()