通过python在网络上传输文件夹的内容

时间:2017-11-28 19:00:49

标签: python sockets networking file-transfer

我在使用Python编写程序以通过网络发送文件夹内容时遇到问题。那里有很多例子,我发现的所有例子都假设接收方知道他想要接收的文件的名称。我试图做的程序,假设接收方同意接收文件,并且不需要从服务器请求其名称的文件。一旦服务器和客户端之间建立了连接,服务器就会开始将特定文件夹中的所有文件发送到客户端。这是一张显示更多解释的图片:example here

以下是一些执行客户端服务器的程序,但是它们发送一个文件并假设接收方知道名称,所以他请求它以便接收它。

https://www.youtube.com/watch?v=LJTaPaFGmM4

http://www.bogotobogo.com/python/python_network_programming_server_client_file_transfer.php

python socket file transfer

以下是我发现的最佳示例:

服务器端:

import sys

import socket

import os

workingdir = "/home/SomeFilesFolder"

host = ''
skServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
skServer.bind((host, 1000))
skServer.listen(10)
print "Server Active"
bFileFound = 0

while True:
    Content, Address = skServer.accept()
    print Address
    sFileName = Content.recv(1024)
    for file in os.listdir(workingdir):
        if file == sFileName:
            bFileFound = 1
            break

    if bFileFound == 0:
        print sFileName + " Not Found On Server"

    else:
        print sFileName + " File Found"
        fUploadFile = open("files/" + sFileName, "rb")
        sRead = fUploadFile.read(1024)
        while sRead:
            Content.send(sRead)
            sRead = fUploadFile.read(1024)
        print "Sending Completed"
    break

Content.close()
skServer.close()

客户方:

import sys

import socket

skClient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
skClient.connect(("ip address", 1000))

sFileName = raw_input("Enter Filename to download from server : ")
sData = "Temp"

while True:
    skClient.send(sFileName)
    sData = skClient.recv(1024)
    fDownloadFile = open(sFileName, "wb")
    while sData:
        fDownloadFile.write(sData)
        sData = skClient.recv(1024)
    print "Download Completed"
    break

skClient.close()

如果有办法从客户端消除此声明:

sFileName = raw_input("Enter Filename to download from server : ")

并使服务器端逐个发送所有文件,而无需等待客户端选择文件。

2 个答案:

答案 0 :(得分:1)

这里是一个示例,该示例以递归方式将“服务器”子目录中的所有内容发送给客户端。客户端会将收到的所有内容保存在“客户端”子目录中。服务器为每个文件发送:

  1. 相对于服务器子目录的路径和文件名,采用UTF-8编码并以换行符终止。
  2. 文件大小(以UTF-8编码的字符串开头,以换行符结尾),以十进制表示。
  3. 文件数据的确切“文件大小”字节。

所有文件传输完毕后,服务器关闭连接。

server.py

from socket import *
import os

CHUNKSIZE = 1_000_000

sock = socket()
sock.bind(('',5000))
sock.listen(1)

while True:
    print('Waiting for a client...')
    client,address = sock.accept()
    print(f'Client joined from {address}')
    with client:
        for path,dirs,files in os.walk('server'):
            for file in files:
                filename = os.path.join(path,file)
                relpath = os.path.relpath(filename,'server')
                filesize = os.path.getsize(filename)

                print(f'Sending {relpath}')

                with open(filename,'rb') as f:
                    client.sendall(relpath.encode() + b'\n')
                    client.sendall(str(filesize).encode() + b'\n')

                    # Send the file in chunks so large files can be handled.
                    while True:
                        data = f.read(CHUNKSIZE)
                        if not data: break
                        client.sendall(data)
        print('Done.')

客户端创建“客户端”子目录并连接到服务器。在服务器关闭连接之前,客户端将接收路径和文件名,文件大小以及文件内容,并在“ client”子目录下的路径中创建文件。

client.py

from socket import *
import os

CHUNKSIZE = 1_000_000

# Make a directory for the received files.
os.makedirs('client',exist_ok=True)

sock = socket()
sock.connect(('localhost',5000))
with sock,sock.makefile('rb') as clientfile:
    while True:
        raw = clientfile.readline()
        if not raw: break # no more files, server closed connection.

        filename = raw.strip().decode()
        length = int(clientfile.readline())
        print(f'Downloading {filename}...\n  Expecting {length:,} bytes...',end='',flush=True)

        path = os.path.join('client',filename)
        os.makedirs(os.path.dirname(path),exist_ok=True)

        # Read the data in chunks so it can handle large files.
        with open(path,'wb') as f:
            while length:
                chunk = min(length,CHUNKSIZE)
                data = clientfile.read(chunk)
                if not data: break
                f.write(data)
                length -= len(data)
            else: # only runs if while doesn't break and length==0
                print('Complete')
                continue

        # socket was closed early.
        print('Incomplete')
        break 

在与server.py相同的目录中的“服务器”子目录下放置任意数量的文件和子目录。运行服务器,然后在另一个终端中运行client.py。将创建一个客户端子目录,并将“服务器”下的文件复制到其中。

答案 1 :(得分:0)

您需要使用os.listdir()发送json.dumps()并将其编码为utf-8 在客户端,您需要解码并使用json.loads(),以便将列表传输到客户端 将sData = skClient.recv(1024)放在sFileName = raw_input("Enter Filename to download from server : ")之前,以便可以显示服务器文件列表 您可以在这里找到一个有趣的工具 https://github.com/manoharkakumani/mano