如何使用套接字发送多个音乐文件?

How to send multiple music files using sockets?

我正在使用 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()

如有任何建议,我们将不胜感激。谢谢。

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()

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

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

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

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

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

import tftpy

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

在具有文件 start 客户端的机器上:

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)