python socket接收数据不完整_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()转换为网络字节顺序,请!)或作为字符串后跟某个分隔符(如“123:”)。第二种方法通常效率较低,但在Python中更容易实现。

一旦将其添加到协议中,就需要更改代码来处理随时返回任意数量数据的recv()。下面是一个如何做到这一点的例子。我试着把它写成伪代码,或者用注释告诉你该怎么做,但不是很清楚。所以我用长度前缀作为以冒号结尾的数字字符串显式地写了它。给你: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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值