我正在努力使用套接字实现一些“精确”的数据交换。我有一个程序可以使用这些套接字发送/接收文件,我已经准备好在第一阶段发送文件名和文件大小。你知道吗
一切似乎都很好,但有时收到的数据不是预期的数据。我猜接收到的数据是同时到达的两个Tx“发送操作”的数据,因此我对接收到的字符串的预期“解析”不正确,它崩溃了。你知道吗
目前我的代码对于接收器是这样的:
while True:
c, addr = self.s.accept()
l = c.recv(1024)
while (l):
if stage < 2:
self.__recvHeader(l)
stage += 1
else:
self.f.write(l)
l = c.recv(1024)
作为__recvHeader
函数:
def __recvHeader(self, data):
line = data.decode("utf-8").split(":")
if line[0] == "Name":
self.filename = line[1]
self.f = open("/tmp/" + self.filename, 'wb')
elif line[0] == "Size":
self.size = int(line[1])
else:
print("ERROR: " + "".join(line))
而Tx的作用是:
# Here I send some headers first, then
l = f.read(1024)
while (l):
self.s.send(l)
l = f.read(1024)
sendHeader函数为:
def __sendHeader(self, name, value):
self.s.send((name + ":" + value).encode('utf-8'))
对我来说,这个问题似乎是我不能为头设置一个固定的长度,因为文件名和文件大小可能会改变。你知道吗
你知道如何处理这个问题吗?或者我如何将这些数据转换成固定大小的数据来避免这个问题?最后一个选项也需要一个不同的“解析”IMO,不是吗?你知道吗
我假设您使用的是TCP/IP套接字。TCP/IP是一种流协议,对您的数据结构一无所知。如果您在一次
send()
操作中发送“消息”,则不能保证它会在一次recv()
操作中到达。或者一个recv()
操作将只接收一条“消息”。在您的例子中,头是一条消息。你知道吗因此,您必须以某种方式对消息进行分隔,以便接收方能够正确地接收和解析它们。基本上有两种选择:
在第一个选项中,您必须考虑如何发送长度。如果使用多字节值,例如32位值,则可能需要在发送之前将其转换为网络字节顺序。见htonl。你知道吗
在第二个选项中,您可以逐字节
recv()
,但这将非常缓慢。您可能需要使用某种缓冲。你知道吗确保您使用的套接字为:
socket.SOCK_STREAM
!这意味着套接字使用TCP,它确保您的数据按顺序到达(在合理的“保证”范围内)。如果问题仍然存在,请继续阅读。。。你知道吗我将首先base64对您的文件进行编码,以消除数据中的任何奇怪之处。base64使用limited alphabet对数据进行编码。因此,添加一个不在该字母表中的标记符号既简单又安全。您可以直接执行(伪代码):
你只要发送
"$<base64filecontent>$"
。你知道吗相关问题 更多 >
编程相关推荐