0

我正在使用 python 3.6 和 ubuntu 18.04。

我能够使用socket-python(以二进制模式)发送单个音乐文件,并且我想将多个音乐文件从服务器发送到客户端。

问题是,在接收端(即客户端),所有音乐文件(从服务器发送的大约 120 个文件)都收集在一个文件中,使其成为一个 9 小时长的单个音乐文件。

我尝试使用 time.sleep 方法(不起作用),尝试发送虚假元素(显示错误)并尝试发送一些随机字符以在客户端结束文件写入并启动新文件写入(但随机字符需要编码和解码,因此再次出错,因为二进制数据无法解码)。

服务器代码

import socket
import os
import send_file
import time


s = socket.socket()
host = ""
port = 9997

s.bind((host, port))
s.listen(5)
print("Binding Done\n")

socket_object, address = s.accept()
print("Connection Established\n")

print("Sending file...")
file_class = send_file.send_files() #ignore
file_names = file_class.files #ignore - contains list of path of music file
socket_object.sendall( str(len(file_names)).encode() )

for i in file_names:
    f = open(i, 'rb')
    buf = f.read(1024)
    while buf:
        socket_object.sendall(buf)
        buf = f.read(1024)
    f.close()

print("Files Send")
socket_object.close()
s.close()

客户代码

import socket
import os
import time


def recv_file(i):
    f = open("/home/ravi/PycharmProjects/File_Transfer/B/"+"M"+str(i)+".mp3", 'wb')
    buf = s.recv(1024)
    while buf:
        f.write(buf)
        buf = s.recv(1024)
    f.close()


s = socket.socket()
host = "127.0.0.1"
port = 9997
s.connect((host, port))


print("Receiving data...")
l = s.recv(1024).decode() #ignore - length of total number of files i.e., 120 approx
for i in range(int(l)):
    recv_file(i+1)


print("Files Collected")
s.close()

任何建议,将不胜感激。谢谢你。

4

1 回答 1

0

TCP 是一种面向流的协议。它是为发送数据流而设计的。在 TCP 级别没有文件。它不会在任何面向文件的块中拆分流。

看看你的代码:

for i in file_names:
    f = open(i, 'rb')
    buf = f.read(1024)
    while buf:
        socket_object.sendall(buf)
        buf = f.read(1024)
    f.close()

您只需将所有文件粘合到一个流中,您的客户端不知道一个文件何时结束,下一个文件何时开始。

通过 TCP 发送多个文件的任务可以通过多种方式解决:

  1. 开发自己的协议。例如:首先发送文件的数量,然后发送一个 8 字节编码文件长度的数组,然后是文件内容流。接收端读取文件数量,然后解析文件长度。知道接收器正确地将流拆分为文件的长度。
  2. 使用现有的多文件打包格式:tar、cpio、zip 等。发送前打包文件,然后发送生成的包。在接收端收到后打开包装。
  3. 推荐方式使用现有协议通过 TCP 发送文件:TFTP 或 FTP。

我建议使用 TFTP。它非常简单且相当有效。Python中有几种实现,例如tftpy

在要将文件上传到的远程计算机上,启动 TFTP 服务器:

import tftpy

server = tftpy.TftpServer('<destination-folder>')
server.listen('0.0.0.0', 54321)

在有文件的机器上启动客户端:

import tftpy

client = tftpy.TftpClient('your.server.address', 54321)
for name in ("fileA", "fileB", "fileC"):
    # the first argument is the name on the remote machine
    # the second argument is the name on the local machine
    client.upload(name, name)
于 2020-02-06T09:27:52.107 回答