gpt4 book ai didi

python - python socket.recv() 方法如何知道已经到达消息结尾?

转载 作者:太空狗 更新时间:2023-10-29 22:25:08 26 4
gpt4 key购买 nike

假设我使用 1024 作为我的客户端套接字的缓冲区大小:

recv(1024)

假设服务器要发送给我的消息包含 2024 个字节。我的套接字只能接收 1024 个字节。其他 1000 字节发生了什么?

  1. recv 方法是否会等待一定的时间(比如 2 秒)以接收更多数据并在这段时间后停止工作? (即,如果剩余数据在 3 秒后到达,则套接字将不再接收数据?)

  1. recv-method 在收到 1024 字节的数据后会立即停止工作吗? (即会丢弃其他 1000 个字节吗?)

如果 1.) 是正确的...我有没有办法确定接收数据在返回之前应该等待的时间量,还是由系统确定? (即我可以告诉套接字在停止等待更多数据之前等待 5 秒吗?)

更新:假设,我有以下代码:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], port))
s.send('Hello, world')
data = s.recv(1024)
print("received: {}".format(data))
s.close()

假设服务器发送大小> 1024 字节的数据。我可以确定变量“数据”将包含所有数据(包括第 1024 个字节以外的数据)吗?如果我不能确定这一点,我将如何更改代码以便我始终可以确保变量“数据”将包含从服务器(通过一个或多个步骤)发送的所有数据?

最佳答案

这取决于协议(protocol)。某些协议(protocol)(如 UDP)发送消息并且每次 recv 仅返回 1 条消息。假设您专门谈论 TCP,则涉及多个因素。 TCP 是面向流的,由于当前未完成的发送/接收数据量、线路上丢失/重新排序的数据包、延迟的数据确认以及 Nagle 算法(将一些小的发送延迟几百毫秒),它的随着客户端和服务器之间对话的进行,行为可能会发生微妙的变化。

接收者只知道它正在获取字节流。它可以在任何 recv 上获取从 1 到完全请求的缓冲区大小的任何内容。一侧的发送调用与另一侧的接收调用之间没有一对一的关联。

如果您需要确定消息边界,则需要更高级别的协议(protocol)来确定。以 HTTP 为例。它以\r\n 分隔的 header 开头,然后计算客户端应该接收的剩余字节数。客户端知道如何读取 header ,因为\r\n 然后确切地知道接下来有多少字节。 RESTful 协议(protocol)的部分魅力在于它们是基于 HTTP 的,而其他人已经解决了这个问题!

一些协议(protocol)使用 NUL 来分隔消息。其他人可能有一个固定长度的二进制头,其中包括对即将到来的任何可变数据的计数。我喜欢zeromq它在 TCP 之上具有强大的消息传递系统。

关于 receive 发生的事情的更多细节...

当你执行recv(1024)时,有6种可能

  1. 没有接收数据。 recv 会等待直到有接收数据。您可以通过设置超时来更改它。

  2. 有部分接收数据。你会马上得到那部分。其余部分要么已缓冲,要么尚未发送,您只需执行另一次接收即可获得更多(同样的规则适用)。

  3. 有超过 1024 个字节可用。您将获得 1024 个数据,其余数据缓冲在内核中等待下一次接收。

  4. 对方关闭了socket。您将获得 0 字节的数据。 0 意味着您永远不会在该套接字上获得更多数据。但是,如果您一直要求数据,您将一直得到 0 字节。

  5. 另一方已重置套接字。你会得到一个异常(exception)。

  6. 其他一些奇怪的事情发生了,你会得到一个异常(exception)。

关于python - python socket.recv() 方法如何知道已经到达消息结尾?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41382127/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com