我在使用Python编写程序以通过网络发送文件夹内容时遇到问题。那里有很多例子,我发现的所有例子都假设接收方知道他想要接收的文件的名称。我试图做的程序,假设接收方同意接收文件,并且不需要从服务器请求其名称的文件。一旦服务器和客户端之间建立了连接,服务器就会开始将特定文件夹中的所有文件发送到客户端。这是一张显示更多解释的图片:example here
以下是一些执行客户端服务器的程序,但是它们发送一个文件并假设接收方知道名称,所以他请求它以便接收它。
https://www.youtube.com/watch?v=LJTaPaFGmM4
http://www.bogotobogo.com/python/python_network_programming_server_client_file_transfer.php
以下是我发现的最佳示例:
服务器端:
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 : ")
并使服务器端逐个发送所有文件,而无需等待客户端选择文件。
答案 0 :(得分:1)
这里是一个示例,该示例以递归方式将“服务器”子目录中的所有内容发送给客户端。客户端会将收到的所有内容保存在“客户端”子目录中。服务器为每个文件发送:
所有文件传输完毕后,服务器关闭连接。
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