gpt4 book ai didi

python - 如何可靠地从 TCP 套接字中准确读取 n 个字节?

转载 作者:行者123 更新时间:2023-12-03 11:49:29 30 4
gpt4 key购买 nike

语境:

二进制协议(protocol)通常定义给定大小的帧。 struct模块擅长解析,前提是所有内容都已在单个缓冲区中接收。

问题:

TCP 套接字是流。从套接字读取不能提供比请求更多的字节,但是 可以返回少。所以这段代码不可靠:

def readnbytes(sock, n):
return sock.recv(n) # can return less than n bytes

天真的解决方法:
def readnbytes(sock, n):
buff = b''
while n > 0:
b = sock.recv(n)
buff += b
if len(b) == 0:
raise EOFError # peer socket has received a SH_WR shutdown
n -= len(b)
return buff

可能效率不高,因为如果我们要求大量的字节,而数据如果非常碎片化,我们会反复重新分配一个新的字节缓冲区。

问题:

怎样才能可靠地从流套接字准确接收 n 个字节而没有重新分配的风险?

引用:

这些其他问题是相关的,并且确实给出了提示,但没有一个给出简单而明确的答案:
  • How to receive certain size of data in socket programming?
  • How do I use ctypes to recv_into a C buffer multiple times?
  • 最佳答案

    您可以使用socket.makefile()将套接字包装在类似文件的对象中。然后读取将准确返回请求的数量,除非套接字关闭,它可以返回剩余部分。这是一个例子:

    服务器.py

    from socket import *

    sock = socket()
    sock.bind(('',5000))
    sock.listen(1)
    with sock:
    client,addr = sock.accept()
    with client, client.makefile() as clientfile:
    while True:
    data = clientfile.read(5)
    if not data: break
    print(data)

    客户端.py
    from socket import *
    import time

    sock = socket()
    sock.connect(('localhost',5000))
    with sock:
    sock.sendall(b'123')
    time.sleep(.5)
    sock.sendall(b'451234')
    time.sleep(.5)
    sock.sendall(b'51234')

    服务器输出

    12345
    12345
    1234

    关于python - 如何可靠地从 TCP 套接字中准确读取 n 个字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55825905/

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