我是Python的初学者,所以请考虑我不能一次性提供完整的信息。
我的要求是:
我正在实现一个基于Python的套接字接收器。实现已完成,但我必须处理以下消息/数据流:
1)数据流中将包含4种不同类型的消息。每个都有一个消息标题(1-4),我正在使用
type_msg=struct.unpack('B',data[0])[0]
2)第二部分是接下来的4位将根据标题具有每种类型的数据的实际长度。所以,
actual_len = struct.unpack('i', data[1:5])[0]
3)下一部分是处理收到的数据并使用它。接收数据的长度可以通过** rcv_len = len(data)**
获取我遇到的问题是我收到的数据少于实际长度。我有 delta-length,我使用的是real_len-rcv_len
此后我无法处理代码。到目前为止,接收增量消息然后将其附加到接收数据的最佳方法是什么。我还想将数据写入文件。
我已经阅读过data.append但不太确定如何实现它。我是否应该再次使用 conn.recv(del_len)接收数据或执行其他操作。
任何指导都会非常有帮助。
下面添加代码:
BUFFER_SIZE=40960
import socket
import struct
class mySocket:
def __init__(self, sock=None):
if sock is None:
self.sock = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
self.sock.bind(('', 9988))
self.sock.listen(1)
else:
self.sock = sock
def receive_data(self):
# Wait for a connection
print >>sys.stderr, 'waiting for a connection'
conn, client_address= self.sock.accept()
print "Connected to client with IP---->", client_address
while True:
data = conn.recv(BUFFER_SIZE)
if not data:
print "Connection is Broken.."
break
else:
if data<5:
print "MSG HEADER STILL NOT COMPLETELY RECEIVED"
else:
type_msg=struct.unpack('B',data[0])
msg_type = type_msg[0]
rcv_len = len(data)
actual_len = struct.unpack('i', data[1:5])[0]
print "Received Length: ",rcv_len
print "Actual Length : ",actual_len
if msg_type == 1:
f_cfg = open("test.xml", "wb")
if rcv_len < actual_len:
del_len = actual_len-rcv_len
print "Delta length :",del_len
while (del_len):
print "Receiving Falcon Config File..."
print "Actual Length : ",actual_len,"and total length now is",rcv_len+del_len
f_cfg.write(data[5:rcv_len]+data[del_len]) //Feel something wrong in this.
else:
print "Writing Falcon config"
f_cfg.write(data[5:])
f_cfg.close()
else:
print "INVALID MESSAGE TYPE. DATA CORRUPTED !!"
break
conn.send("Data Received")
conn.close()
答案 0 :(得分:0)
你非常接近。这些技巧永远不会读取任何步骤所需的数据,因此您不必担心过度拍摄。只需通过减去每次收到的金额来跟踪剩余的数据,这样您就不必处理多个变量。
这是一个将在固定大小的缓冲区中读取的帮助程序。用它来读入标题。
def recv_exactly(sock, count):
"""receive exactly count bytes from socket. If socket is closed,
empty string is returned even if some data received.
"""
buf = []
while count:
data = sock.recv(count)
if not data:
return ''
count -= len(data)
buf.append(data)
return ''.join(buf)
您可以使用相同的函数读取数据,但最好随时编写文件。请注意,在接收数据时,min
函数用于决定recv大小。
def receive_data(self):
# Wait for a connection
print >>sys.stderr, 'waiting for a connection'
conn, client_address= self.sock.accept()
print "Connected to client with IP---->", client_address
while True:
# read fix length header
data = recv_exactly(conn, 5)
if not data:
print "Connection is Broken.."
break
msg_type, data_len = struct.unpack('Bi', data)
if msg_type == 1:
# read stream into file
with open('test.xml', 'wb') as fp:
while data_len:
# read next chunk. on the last chunk, limit recv to the
# known amount of outstanding data
data = conn.recv(min(data_len, BUFFER_SIZE))
if not data:
print "ERROR: TOO FEW BYTES RECEIVED"
break
fp.write(data)
data_len -= len(data)
conn.send("Data Received")
conn.close()