通过c中的套接字原子地发送整数
Sending integer atomically over a socket in c
我有一个简单的客户端,它通过套接字从服务器接受单个 uint32_t。使用此处多次出现的解决方案(例如 transfer integer over a socket in C)似乎可行,但是:
在文件上调用 "read" 时,我知道系统不能保证一次读取消息的全部内容,因此它 returns 读取的字节数。通过网络套接字接受 4 个字节时不会发生同样的情况吗?
如果这不可能发生,那是为什么?如果可以,如何确保发送是 "atomic",或者是否有必要自己拼凑字节?
如果底层协议是TCP/IP,是面向流的(没有"packets"或"messages",只有两个字节流),那么是。
您需要注意管理读取的数据量,以便了解每个 "message"(在您的情况下为单个整数)的开始和结束位置。
When calling "read" on files I know that the system is not guaranteed
to read the entire content of the message at once
这是错误的,如果请求的字节数可用,则读取它们:
POSIX read manual says: The value returned may be less than nbyte if the number of bytes left
in the file is less than nbyte
这至少对于常规文件是正确的,对于管道等类似情况则不同。
Couldn't the same happen when accepting 4 bytes over a network socket?
(我想你在谈论 TCP 套接字。)套接字可能会发生这种情况,因为底层协议可能会以任何合适的方式传输你的字节(例如阅读 TCP 碎片),唯一确保的是如果接收到字节收到的顺序与发送的顺序相同。因此,要读取给定数量的字节,您必须尝试用几个 read
最终读取这些字节。这通常是通过遍历 read
直到接收并读取所需的字节来完成的。
根据套接字类型,可以使用不同的协议。 SOCK_STREAM(对应于网络套接字上的TCP)是一种面向流的协议,因此数据包可能会被发送方、接收方或中间的任何设备重新组合。
但是SOCK_DGRAM (UDP) 或SOCK_SEQPACKET 实际上发送的数据包是无法更改的。在那种情况下,同一个数据包中的 4 个字节保证在同一个读取操作中可用,除非接收缓冲区太小。来自 man socket:
If a message is too long to fit in the supplied buffer, excess
bytes may be discarded depending on the type of socket the message is
received from
因此,如果您想要 atomic 块,请使用数据包协议而不是流协议,并确保有足够大的接收缓冲区。
我有一个简单的客户端,它通过套接字从服务器接受单个 uint32_t。使用此处多次出现的解决方案(例如 transfer integer over a socket in C)似乎可行,但是:
在文件上调用 "read" 时,我知道系统不能保证一次读取消息的全部内容,因此它 returns 读取的字节数。通过网络套接字接受 4 个字节时不会发生同样的情况吗?
如果这不可能发生,那是为什么?如果可以,如何确保发送是 "atomic",或者是否有必要自己拼凑字节?
如果底层协议是TCP/IP,是面向流的(没有"packets"或"messages",只有两个字节流),那么是。
您需要注意管理读取的数据量,以便了解每个 "message"(在您的情况下为单个整数)的开始和结束位置。
When calling "read" on files I know that the system is not guaranteed to read the entire content of the message at once
这是错误的,如果请求的字节数可用,则读取它们:
POSIX read manual says: The value returned may be less than nbyte if the number of bytes left in the file is less than nbyte
这至少对于常规文件是正确的,对于管道等类似情况则不同。
Couldn't the same happen when accepting 4 bytes over a network socket?
(我想你在谈论 TCP 套接字。)套接字可能会发生这种情况,因为底层协议可能会以任何合适的方式传输你的字节(例如阅读 TCP 碎片),唯一确保的是如果接收到字节收到的顺序与发送的顺序相同。因此,要读取给定数量的字节,您必须尝试用几个 read
最终读取这些字节。这通常是通过遍历 read
直到接收并读取所需的字节来完成的。
根据套接字类型,可以使用不同的协议。 SOCK_STREAM(对应于网络套接字上的TCP)是一种面向流的协议,因此数据包可能会被发送方、接收方或中间的任何设备重新组合。
但是SOCK_DGRAM (UDP) 或SOCK_SEQPACKET 实际上发送的数据包是无法更改的。在那种情况下,同一个数据包中的 4 个字节保证在同一个读取操作中可用,除非接收缓冲区太小。来自 man socket:
If a message is too long to fit in the supplied buffer, excess bytes may be discarded depending on the type of socket the message is received from
因此,如果您想要 atomic 块,请使用数据包协议而不是流协议,并确保有足够大的接收缓冲区。