为了账号安全,请及时绑定邮箱和手机立即绑定

Python套接字接收大量数据

Python套接字接收大量数据

不负相思意 2019-10-06 15:54:23
当我尝试接收大量数据时,该数据将被切断,我必须按Enter键才能获取其余数据。最初,我可以将其增加一点,但仍然无法收到全部。如您所见,我增加了conn.recv()上的缓冲区,但它仍然无法获取所有数据。它在某个点将其切断。我必须在raw_input上按Enter键才能接收其余数据。无论如何,我可以一次获取所有数据吗?这是代码。port = 7777sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.bind(('0.0.0.0', port))sock.listen(1)print ("Listening on port: "+str(port))while 1:    conn, sock_addr = sock.accept()    print "accepted connection from", sock_addr    while 1:        command = raw_input('shell> ')            conn.send(command)                data = conn.recv(8000)                if not data: break                print data,    conn.close()
查看完整描述

3 回答

?
茅侃侃

TA贡献1842条经验 获得超21个赞

TCP / IP是基于流的协议,而不是基于消息的协议。不能保证send()一个对等方的每个呼叫都会导致另一对等方的单个recv()呼叫接收到发送的确切数据recv(),由于数据包分段,它可能会接收到数据块,并分成多个呼叫。


您需要在TCP之上定义自己的基于消息的协议,以区分消息边界。然后,要阅读消息,请继续呼叫recv()直到您阅读了整个消息或发生错误为止。


发送消息的一种简单方法是为每个消息加上前缀。然后要读取一条消息,您首先要读取长度,然后读取那么多字节。您可以按照以下方式进行操作:


def send_msg(sock, msg):

    # Prefix each message with a 4-byte length (network byte order)

    msg = struct.pack('>I', len(msg)) + msg

    sock.sendall(msg)


def recv_msg(sock):

    # Read message length and unpack it into an integer

    raw_msglen = recvall(sock, 4)

    if not raw_msglen:

        return None

    msglen = struct.unpack('>I', raw_msglen)[0]

    # Read the message data

    return recvall(sock, msglen)


def recvall(sock, n):

    # Helper function to recv n bytes or return None if EOF is hit

    data = b''

    while len(data) < n:

        packet = sock.recv(n - len(data))

        if not packet:

            return None

        data += packet

    return data

然后,您可以使用send_msg和recv_msg函数来发送和接收整个消息,并且它们不会在网络级别拆分或合并数据包时带来任何问题。


查看完整回答
反对 回复 2019-10-06
?
当年话下

TA贡献1890条经验 获得超9个赞

您可以将其用作: data = recvall(sock)


def recvall(sock):

    BUFF_SIZE = 4096 # 4 KiB

    data = b''

    while True:

        part = sock.recv(BUFF_SIZE)

        data += part

        if len(part) < BUFF_SIZE:

            # either 0 or end of data

            break

    return data


查看完整回答
反对 回复 2019-10-06
?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

可以接受的答案很好,但是对于大文件来说这确实会很慢-string是一个不可变的类,这意味着每次使用+符号时都会创建更多对象,将其list用作堆栈结构会更有效。


这应该更好地工作


while True: 

    chunk = s.recv(10000)

    if not chunk: 

        break

    fragments.append(chunk)


print "".join(fragments)


查看完整回答
反对 回复 2019-10-06
  • 3 回答
  • 0 关注
  • 894 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信