我正在使用 python 3.x 和套接字模块。服务器在 ipv4 地址上运行并使用 tcp。
我阅读了一些有关如何发送和接收数据的教程。对于服务器或客户端,要确保发送整个消息,您可以简单地检查发送的数据量是否等于消息的大小:
def mysend(self, msg):
totalsent = 0
while totalsent < MSGLEN:
sent = self.sock.send(msg[totalsent:])
if sent == 0:
raise RuntimeError("socket connection broken")
totalsent = totalsent + sent
Source: https://docs.python.org/3/howto/sockets.html#socket-howto https://docs.python.org/3/howto/sockets.html#socket-howto
并让客户确保已收到完整的回复本教程 https://realpython.com/python-sockets/#multi-connection-client-and-server建议在响应的开头添加响应的大小。
我的问题:
- 如何确保我收到指示消息大小的消息的第一部分(假设我的消息包含 1000 个字符,我需要四个字符来指示大小)?
- 为什么我不能在消息开头添加特定符号,例如“”,以便我知道消息的开始和结束位置?
Edit:
- 当我使用
sock.recv(1024)
我的消息只有 500 到 1000 个字符,这不能确保我收到所有消息吗?
首先,要发送所有字节,不需要循环,因为 python 套接字提供了一个简单的方法:socket.sendall() https://docs.python.org/3/library/socket.html#socket.socket.sendall.
现在回答你的问题:
是的,即使只接收 4 个字节,您也应该有一个接收循环来调用recv() https://docs.python.org/3/library/socket.html#socket.socket.recv直到读取 4 个字节。
你可以,if您可以保证此类字符不会出现在消息本身中。但是,您仍然需要搜索读入的每个字符来查找魔术分隔符,因此它似乎不如简单地在消息正文前添加长度前缀。
你打电话时recv(n) https://docs.python.org/3/library/socket.html#socket.socket.recv只能保证返回at mostn 个字节,不完全是 n 个字节。
这里有三种不同的recvall()
比较方法:
def recvall(sock, size):
received_chunks = []
buf_size = 4096
remaining = size
while remaining > 0:
received = sock.recv(min(remaining, buf_size))
if not received:
raise Exception('unexpected EOF')
received_chunks.append(received)
remaining -= len(received)
return b''.join(received_chunks)
和更短的
def recvall2(sock, size):
return sock.recv(size, socket.MSG_WAITALL)
最后是另一个版本,它比第一个版本短一些,但缺少一些功能:
def recvall3(sock, size):
result = b''
remaining = size
while remaining > 0:
data = sock.recv(remaining)
result += data
remaining -= len(data)
return result
第二个很好而且很短,但它依赖于套接字选项socket.MSG_WAITALL
我不相信这一定会存在于每个平台上。第一个和第三个应该在任何地方都有效。我还没有真正对任何基准进行比较和对比。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)