TCP和UDP协议中的记录或数据边界是什么意思?

3

我正在学习套接字并在SOCK_SEQPACKET通信协议中发现了Data或Record Boundaries这个词? 有人能用简单的语言解释一下什么是数据边界,以及SOCK_SEQPACKETSOCK_STREAMSOCK_DGRAM之间的区别吗?

1个回答

3
这个答案https://dev59.com/WGkw5IYBdhLWcg3w6ewb#9563694对消息边界(另一种称呼是“记录边界”)有简洁明了的解释。
将该答案扩展到SOCK_SEQPACKET
  • SOCK_STREAM提供可靠、序列化的数据流通信,但不维护消息(记录)边界,这意味着应用程序必须在所提供的数据流之上管理自己的边界。

  • SOCK_DGRAM提供不可靠的数据报传输。数据报是自包含的信息单元,其边界得以维护。这意味着如果您在A端发送一个20字节的缓冲区,B端将接收到一个20字节的消息。但是,它们可能会被丢弃或乱序接收,因此需要应用程序来处理。

  • SOCK_SEQPACKET是一种新技术,尚未广泛使用,但试图将以上两种技术的优点结合起来。也就是说,它提供了可靠、序列化的通信,同时将整个“数据报”作为一个单元传输(因此维护消息边界)。

最容易演示消息边界概念的方法是展示当它们被忽略时会发生什么。初学者经常在SO上发布这样的客户端代码(为了方便使用Python):
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'。(通常代码中还有其他与时间相关的方面会影响是否发生这种情况。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接