您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Python套接字接收-传入的数据包始终具有不同的大小

Python套接字接收-传入的数据包始终具有不同的大小

网络 总是 不可预测的。TCP使许多这种随机行为为您消除。TCP要做的一件奇妙的事情:它确保字节将以相同的顺序到达。但!它 不能 保证它们会以相同的方式切碎。您根本 无法 假设连接一端的每个send()都会导致远端上的一个recv()的字节数完全相同。

当您说时socket.recv(x),您的意思是“直到您从套接字读取了x个字节后,才返回”。这称为“阻止I / O”:您将阻止(等待)直到您的请求得到满足。如果协议中的每条消息都恰好是1024字节,则调用socket.recv(1024)将非常有用。但这听起来不对。如果您的消息是固定的字节数,只需将该数字传递给socket.recv()您就可以了。

但是,如果您的邮件可以具有不同的长度怎么办?您需要做的第一件事:停止socket.recv()使用明确的电话号码。改变这个:

data = self.request.recv(1024)

对此:

data = self.request.recv()

recv()只要获得新数据,均值将始终返回。

但是现在您遇到了一个新问题:您怎么知道发件人何时向您发送了完整的消息?答案是:您不知道。您将必须使消息的长度成为协议的明确部分。最好的方法是:为每个消息加一个前缀,长度可以是固定大小的整数(使用socket.ntohs()socket.ntohl()Please转换为网络字节顺序),也可以是字符串后跟一些定界符(例如‘123:’)。第二种方法通常效率较低,但在Python中更容易。

Once you’ve added that to your protocol, you need to change your code to handle recv() returning arbitrary amounts of data at any time. Here’s an example of how to do this. I tried writing it as pseudo-code, or with comments to tell you what to do, but it wasn’t very clear. So I’ve written it explicitly using the length prefix as a string of digits terminated by a colon. Here you go:

length = None
buffer = ""
while True:
  data += self.request.recv()
  if not data:
    break
  buffer += data
  while True:
    if length is None:
      if ':' not in buffer:
        break
      # remove the length bytes from the front of buffer
      # leave any remaining bytes in the buffer!
      length_str, ignored, buffer = buffer.partition(':')
      length = int(length_str)

    if len(buffer) < length:
      break
    # split off the full message from the remaining bytes
    # leave any remaining bytes in the buffer!
    message = buffer[:length]
    buffer = buffer[length:]
    length = None
    # PROCESS MESSAGE HERE
python 2022/1/1 18:37:53 有316人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶