以二进制模式读取任何文件,将其附加到字符串,然后通过TCP套接字发送

时间:2018-10-04 21:46:05

标签: python python-3.x sockets

所以我必须向服务器(已经存在)发送特定消息。

此请求采用以下格式:

DO dirname number_of_files [file_size file_name file_data]*

例如,它可以是这样的:

DO dir 2 1421 house.png [binary data I assume?] 1239 info.txt [more binary data?]

如您所见,可以有任意数量的文件。

所以我正在做的是创建一个字符串,在其中附加所有信息,最后将所有信息一起发送,但是我被卡在数据部分。

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(ip, port)
request = "DO " + directory + " " + str(number_of_files)

for file_number in range(0,number_of_files):
    data = open("./" + directory + "/" + files_info[file_number*2], 'rb').read()
    client_request += " " + " ".join(files_info[file_number*2 : 1 + file_number*2]) + " " + data

s.send((request + "\n").encode())

这不起作用,因为我试图将二进制数据追加到字符串(TypeError: must be str, not bytes)中。我在追加之前尝试使用.decode(),但收到utf-8解码器错误(UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte)。我尝试了utf-16和ascii,但也没有用。

我应该以其他方式处理此问题吗?我已经做了更多这样的请求,但是它们都不包含文件中的数据,只包含数字/字符串,因此以前从来都不是问题。

我正在尝试遵循这种格式,因为我现在已经像这样完成了所有代码(而且我展示的这些步骤并非都在同一功能中发生),因此更改发送消息的方式并不是最佳选择

1 个答案:

答案 0 :(得分:1)

这是我简单的工作代码,可以使您的内容更接近您想要的:

import socket

ip = '192.168.10.137'
port = 4043

directory = 'C:/123/'

#with open('1.dat', 'wb') as file:
#    file.write(b'\x00\x01\x1a\xa1')
#with open('2.dat', 'wb') as file:
#    file.write(b'\x00\x01\x00\x00')

file_info = ['1.dat', '2.dat']

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:

    sock.connect((ip, port))

    sock.send(
        'DO {} {}'.format(directory, len(file_info)).encode('UTF-8'))

    for filename in file_info:
        with open(filename, mode='rb') as file:
            data = file.read()
        sock.send(
            ' {} '.format(len(data)).encode('UTF-8'))
        sock.send(
            '{} '.format(filename).encode('UTF-8'))
        sock.send(data)

服务器接收的数据(字节):

b'DO C:/123/ 2 4 1.dat \x00\x01\x1a\xa1 4 2.dat \x00\x01\x00\x00'