我使用Tor和袜子设置了一个安全套接字,但是在发送大量数据时遇到了问题
发件人:
socket.send(message.encode())
收件人:
chunks = []
while 1:
part = connection.recv(4096)
chunks.append(part.decode())
if len(part) < 4096:
break
response = "".join(chunks)
由于循环中的网络速度不一致,所以我并不总是填充4096b缓冲区,所以循环中断了,我也没有收到完整的数据。
减小缓冲区的大小似乎不是一种选择,因为“数据包”的大小有时可以低至20b
答案 0 :(得分:0)
TCP可以将程序包数据拆分为任意数量。因此,您从不永远不要将套接字的另一端依赖于接收到的数据包的大小。您必须发明另一种机制来检测消息结尾/文件结尾。
如果仅发送一个Blob并关闭套接字,则在服务器端只需读取,直到获得False值为止:
while True:
data = sock.recv(1024)
if data:
print(data)
# continue
else:
sock.close()
break
如果要发送多条消息,则必须决定它们之间的分隔符是什么。对于文本协议,最好使用行尾。然后,您可以享受Twisted LineReceiver
协议和其他协议的强大功能。
如果您正在执行二进制协议,通常的做法是在每条消息的开头加上字节/字/双字大小。
答案 1 :(得分:0)
尝试使用结构将传入数据的长度首先传递给接收器“导入结构”。这样,接收端便确切知道要接收多少数据。在此示例中,字节是通过套接字发送的,这里的示例是我从github上传github.com/nsk89/netcrypt借来的示例,以供参考,并从send函数以及发送序列化字典中切出了加密步骤。
编辑我还应该澄清一下,当您通过套接字发送数据时,尤其是当您发送多条消息时,它们都作为一条长消息而位于流中。并非每条消息的长度都为4096字节。如果一个长度为2048,下一个为4096,则在缓冲区上收到4096时,您将收到第一条消息以及下一条消息的一半,或者完全挂起,等待更多不存在的数据。
data_to_send = struct.pack('>I', len(data_to_send)) + data_to_send # pack the length of data in the first four bytes of data stream, >I indicates internet byte order
socket_object.sendall(data_to_send) # transport data
def recv_message(socket_object):
raw_msg_length = recv_all(socket_object, 4) # receive first 4 bytes of data in stream
if not raw_msg_length:
return None
# unpack first 4 bytes using network byte order to retrieve incoming message length
msg_length = struct.unpack('>I', raw_msg_length)[0]
return recv_all(socket_object, msg_length) # recv rest of stream up to message length
def recv_all(socket_object, num_bytes):
data = b''
while len(data) < num_bytes: # while amount of data recv is less than message length passed
packet = socket_object.recv(num_bytes - len(data)) # recv remaining bytes/message
if not packet:
return None
data += packet
return data
答案 2 :(得分:0)
顺便说一句,在将它们组合成一个块之前,无需解码每个部分,将所有部分组合成一个块,然后解码该块即可。
针对您的情况,更好的方法是使用2个步骤。
第一步:发送方发送消息的大小,接收方采用此大小并准备接收消息。
步骤2:发送方发送消息,接收方根据需要合并数据。
发件人
# Step 1
socket.send( str(len(message.encode())).encode() )
# Step 2
socket.send(message.encode("utf-8"))
接收器
# Step 1
message_size = connection.recv(1024)
print("Will receive message size:",message_size.decode())
# Step 2
recevied_size = 0
recevied_data = b''
while recevied_size < int(message_size.decode()):
part = connection.recv(1024)
recevied_size += len(part)
recevied_data += part
else:
print(recevied_data.decode("utf-8", "ignore"))
print("message receive done ....",recevied_size)