猿问

Python套接字接收大量数据

当我尝试接收大量数据时,该数据将被切断,我必须按Enter键才能获取其余数据。最初,我可以将其增加一点,但仍然无法收到全部。如您所见,我增加了conn.recv()上的缓冲区,但它仍然无法获取所有数据。它在某个点将其切断。我必须在raw_input上按Enter键才能接收其余数据。无论如何,我可以一次获取所有数据吗?这是代码。


port = 7777

sock = 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()


不负相思意
浏览 895回答 3
3回答

茅侃侃

TCP / IP是基于流的协议,而不是基于消息的协议。不能保证send()一个对等方的每个呼叫都会导致另一对等方的单个recv()呼叫接收到发送的确切数据recv(),由于数据包分段,它可能会接收到数据块,并分成多个呼叫。您需要在TCP之上定义自己的基于消息的协议,以区分消息边界。然后,要阅读消息,请继续呼叫recv()直到您阅读了整个消息或发生错误为止。发送消息的一种简单方法是为每个消息加上前缀。然后要读取一条消息,您首先要读取长度,然后读取那么多字节。您可以按照以下方式进行操作:def send_msg(sock, msg):&nbsp; &nbsp; # Prefix each message with a 4-byte length (network byte order)&nbsp; &nbsp; msg = struct.pack('>I', len(msg)) + msg&nbsp; &nbsp; sock.sendall(msg)def recv_msg(sock):&nbsp; &nbsp; # Read message length and unpack it into an integer&nbsp; &nbsp; raw_msglen = recvall(sock, 4)&nbsp; &nbsp; if not raw_msglen:&nbsp; &nbsp; &nbsp; &nbsp; return None&nbsp; &nbsp; msglen = struct.unpack('>I', raw_msglen)[0]&nbsp; &nbsp; # Read the message data&nbsp; &nbsp; return recvall(sock, msglen)def recvall(sock, n):&nbsp; &nbsp; # Helper function to recv n bytes or return None if EOF is hit&nbsp; &nbsp; data = b''&nbsp; &nbsp; while len(data) < n:&nbsp; &nbsp; &nbsp; &nbsp; packet = sock.recv(n - len(data))&nbsp; &nbsp; &nbsp; &nbsp; if not packet:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return None&nbsp; &nbsp; &nbsp; &nbsp; data += packet&nbsp; &nbsp; return data然后,您可以使用send_msg和recv_msg函数来发送和接收整个消息,并且它们不会在网络级别拆分或合并数据包时带来任何问题。

当年话下

您可以将其用作: data = recvall(sock)def recvall(sock):&nbsp; &nbsp; BUFF_SIZE = 4096 # 4 KiB&nbsp; &nbsp; data = b''&nbsp; &nbsp; while True:&nbsp; &nbsp; &nbsp; &nbsp; part = sock.recv(BUFF_SIZE)&nbsp; &nbsp; &nbsp; &nbsp; data += part&nbsp; &nbsp; &nbsp; &nbsp; if len(part) < BUFF_SIZE:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # either 0 or end of data&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; return data

白猪掌柜的

可以接受的答案很好,但是对于大文件来说这确实会很慢-string是一个不可变的类,这意味着每次使用+符号时都会创建更多对象,将其list用作堆栈结构会更有效。这应该更好地工作while True:&nbsp;&nbsp; &nbsp; chunk = s.recv(10000)&nbsp; &nbsp; if not chunk:&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; fragments.append(chunk)print "".join(fragments)
随时随地看视频慕课网APP

相关分类

Python
我要回答