在字符串消息中发送字节并将其更改回字符串

时间:2017-09-26 14:28:04

标签: python string sockets encoding byte

我在python中编写一个P2P框架,它运行得很好,我用它构建了一个文件共享应用程序。唯一的问题是,我无法弄清楚如何发送二进制类型文件(在这种情况下为zip存档),在下面的代码中,您可以通过我的框架在处理文件时以紧凑的方式查看。

f = open('hhh.zip', 'rb')
filedata = f.read()
f.close()

msg = 'REPLY 5 %s' % filedata
msg = msg.encode('utf-8')

# SENDING

# ...

# RECEIVING

msg = msg.decode('utf-8')
msgtype, msglen, msgdata = msg.split(maxsplit=2)

f = open('received_archive.zip', 'xb')
f.write(msgdata)
f.close()

我正在使用消息结构,其中指示消息类型,消息数据的长度和实际数据。这意味着我不能只发送zip文件的字节,这显然是有效的。发生的事情是我将数据(archive.zip的字节)作为字符串返回,我无法弄清楚如何将其转换回字节,以便我可以编写接收的文件。

我得到的错误如下:

Traceback (most recent call last):
  File "test.py", line 18, in <module>
    f.write(msgdata)
TypeError: a bytes-like object is required, not 'str'

filedata如下: b'PK\x03\x04\n\x00\x00\x00\x00\x00z\xbc7K\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x1c\x00hhhUT\t\x00\x03\xb8\xd3\xc6Y\xb8\xd3\xc6Yux\x0b\x00\x01\x04\xe8\x03\x00\x00\x04\xe8\x03\x00\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00z\xbc7K\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x81\x00\x00\x00\x00hhhUT\x05\x00\x03\xb8\xd3\xc6Yux\x0b\x00\x01\x04\xe8\x03\x00\x00\x04\xe8\x03\x00\x00PK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00I\x00\x00\x00=\x00\x00\x00\x00\x00'

解码后的msgdatabytes(msgdata, 'utf-8')): b"b'PK\\x03\\x04\\n\\x00\\x00\\x00\\x00\\x00z\\xbc7K\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x03\\x00\\x1c\\x00hhhUT\\t\\x00\\x03\\xb8\\xd3\\xc6Y\\xb8\\xd3\\xc6Yux\\x0b\\x00\\x01\\x04\\xe8\\x03\\x00\\x00\\x04\\xe8\\x03\\x00\\x00PK\\x01\\x02\\x1e\\x03\\n\\x00\\x00\\x00\\x00\\x00z\\xbc7K\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x03\\x00\\x18\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xb4\\x81\\x00\\x00\\x00\\x00hhhUT\\x05\\x00\\x03\\xb8\\xd3\\xc6Yux\\x0b\\x00\\x01\\x04\\xe8\\x03\\x00\\x00\\x04\\xe8\\x03\\x00\\x00PK\\x05\\x06\\x00\\x00\\x00\\x00\\x01\\x00\\x01\\x00I\\x00\\x00\\x00=\\x00\\x00\\x00\\x00\\x00'"

没有解码msgdata我得到的第一件事,但作为一个字符串,当试图将其转换回字节时,我得到第二个。

1 个答案:

答案 0 :(得分:0)

同一文件的

bytesstr表示几乎相同,bytes表示可以包含比str更多的内容,包括非unicode数据

如果您想通过网络发送文件类型,则无需区分文件类型。您可以将所有内容视为bytes,以二进制模式读取它们,将它们作为字节发送(实际上python 3赢得了其他任何内容)并以二进制模式写入它们 - 不会丢失任何数据。

with open('hhh.zip', 'rb') as f:
    filedata = f.read()

msg = b'REPLY 5 %s' % filedata  # or equivalent if they still don't support % for bytes

# SENDING
# ...
# RECEIVING

msgtype, msglen, msgdata = msg.split(maxsplit=2)

with open('received_archive.zip', 'xb') as f:
    f.write(msgdata)

此外,根据逻辑,转换为unicode(msg.encode('utf-8'))的东西根本不是人类可读的数据。