问题描述
我正在学习套接字并在 SOCK_SEQPACKET 通信协议中发现数据或记录边界这个词?谁能简单解释一下什么是数据边界以及 SOCK_SEQPACKET 与 SOCK_STREAM 的不同之处?SOCK_DGRAM ?
I am learning to sockets and found the word Data OR Record Boundaries in SOCK_SEQPACKET communication protocol? Can anyone explain in simple words what is Data boundary and how the SOCK_SEQPACKET is different from SOCK_STREAM & SOCK_DGRAM ?
推荐答案
这个答案 https://stackoverflow.com/a/9563694/1076479 对消息边界有很好的简洁解释(记录边界"的不同名称).
This answer https://stackoverflow.com/a/9563694/1076479 has a good succinct explanation of message boundaries (a different name for "record boundaries").
将该答案扩展到SOCK_SEQPACKET
:
SOCK_STREAM
提供可靠、有序的数据流 通信在两个对等点之间.它不维护消息(记录)边界,这意味着应用程序必须在提供的流之上管理自己的边界.
SOCK_STREAM
provides reliable, sequenced communication of streams of data between two peers. It does not maintain message (record) boundaries, which means the application must manage its own boundaries on top of the stream provided.
SOCK_DGRAM
提供不可靠的数据报传输.数据报是自包含的胶囊,它们的边界被保持.这意味着如果您在对等方 A 上发送一个 20 字节的缓冲区,对等方 B 将收到一个 20 字节的消息.但是,它们可能会被丢弃或无序接收,这取决于应用程序来解决和处理它.
SOCK_DGRAM
provides unreliable transmission of datagrams. Datagrams are self-contained capsules and their boundaries are maintained. That means if you send a 20 byte buffer on peer A, peer B will receive a 20 byte message. However, they can be dropped, or received out of order, and it's up to the application to figure that out and handle it.
SOCK_SEQPACKET
是一种较新的技术,尚未广泛使用,但试图将上述两者的优点结合起来.也就是说,它提供了可靠的、有序的通信,还将整个数据报"作为一个单元进行传输(从而保持消息边界).
SOCK_SEQPACKET
is a newer technology that is not yet widely used, but tries to marry the benefits of both of the above. That is, it provides reliable, sequenced communication that also transmits entire "datagrams" as a unit (and hence maintains message boundaries).
通过显示消息边界被忽略时会发生什么来演示消息边界的概念是最简单的.初学者经常在 SO 上发布这样的客户端代码(为方便起见,使用 python):
It's easiest to demonstrate the concept of message boundaries by showing what happens when they're neglected. Beginners often post client code like this here on SO (using python for convenience):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.4.122', 9000))
s.send(b'FOO') # Send string 1
s.send(b'BAR') # Send string 2
reply = s.recv(128) # Receive reply
和服务器代码类似:
lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
lsock.bind(('', 9000))
lsock.listen(5)
csock, caddr = lsock.accept()
string1 = csock.recv(128) # Receive first string
string2 = csock.recv(128) # Receive second string <== XXXXXXX
csock.send(b'Got your messages') # Send reply
他们不明白为什么服务器挂在第二个 recv
调用上,而客户端挂在它自己的 recv
调用上.发生这种情况是因为客户端发送的两个字符串(可能)被捆绑在一起并作为单个单元在服务器端的第一个 recv
中接收.也就是说,两个逻辑消息之间的消息边界没有保留,因此string1
通常会包含两个块一起运行:'FOOBAR'
They don't understand then why the server hangs on the second recv
call, while the client is hung on its own recv
call. That happens because both strings the client sent (may) get bundled together and received as a single unit in the first recv
on the server side. That is, the message boundary between the two logical messages was not preserved, and so string1
will often contain both chunks run together: 'FOOBAR'
(通常还有其他与时间相关的代码方面会影响何时/是否实际发生.)
(Often there are other timing-related aspects to the code that influence when/whether that actually happens or not.)
这篇关于TCP & 意义上的记录或数据边界是什么意思?UDP协议?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!