我有一个简单的客户端,通过套接字从服务器接受单个uint32_t。使用此处出现的解决方案多次(例如transfer integer over a socket in C)似乎有效,但是:
致电"阅读"在文件上我知道系统不能保证一次读取消息的全部内容,因此它返回读取的字节数。当通过网络套接字接受4个字节时,会发生同样的情况吗?
如果这不可能发生,为什么会这样?如果可以的话,怎样才能确保发送是" atomic",还是有必要自己回填字节?
答案 0 :(得分:2)
根据套接字类型,可以使用不同的协议。 SOCK_STREAM(对应于网络套接字上的TCP)是一种面向流的协议,因此数据包可以由发送方,接收方或中间的任何设备重新组合。
但是SOCK_DGRAM(UDP)或SOCK_SEQPACKET实际上发送了无法更改的数据包。在这种情况下,相同数据包中的4个字节保证在相同的读操作中可用,除非接收缓冲区太小。来自男士插座:
如果消息太长而无法容纳在提供的缓冲区中,则过多 可以丢弃字节,具体取决于消息所在的套接字类型 收到
因此,如果您想拥有 atomic 块,请使用数据包协议而不是流协议,并确保拥有足够大的接收缓冲区。
答案 1 :(得分:1)
如果底层协议是TCP / IP,它是面向流的(没有"数据包"或"消息"只有两个字节流),那么是。
您需要注意管理读取数据的数量,以便您可以知道每条消息的位置" (在你的情况下,一个整数)开始和结束。
答案 2 :(得分:1)
在文件上调用“read”时,我知道系统无法保证 一次阅读邮件的全部内容
这是错误的,如果请求的字节数可用,则读取它们:
POSIX阅读手册说:如果剩下的字节数,返回的值可能小于nbyte 在文件中小于nbyte
这对于常规文件至少是正确的,对于管道等都是一个不同的故事。
通过网络套接字接受4个字节时会发生同样的情况吗?
(我想你是在谈论TCP套接字。)这可能发生在套接字上,因为底层协议可能以任何合适的方式传输你的字节(例如,读取有关TCP碎片),唯一确保的是,如果接收到接收的字节按照他们发送的顺序。因此,要读取给定数量的字节,您必须尝试使用多个read
s来读取这些字节。这通常是通过循环read
直到收到并读取所需的字节来完成的。