初学python,使用socket可以传输文件,想传输整个文件夹里的所有的内容,这样两台电脑文件的互传就十分的方便
传输文件夹思路有两个,一个是遍历文件夹下所有的文件,分别发送直到所有的文件传输完成。另一个就是发送端把文件夹打包压缩,传输压缩文件,接收端接收完成后解压。
服务端:接收文件夹
import socket
import os
import sys
import struct
import tarfile
save_path = '接收的文件夹存储地址'
def socket_service():
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1)
s.bind(('本机ip地址', port))
s.listen(2)
except socket.error as msg:
print(msg)
sys.exit(1)
print('waiting..............')
while True:
sock, addr = s.accept()
deal_data(sock, addr, save_path)
extent_tar(save_path)
def deal_data(sock, addr, save_path):
print("Accept from{0}".format(addr))
while True:
fileinfo_size = struct.calcsize('128sq')
buf = sock.recv(fileinfo_size)
if buf:
filename, filesize = struct.unpack('128sq', buf)
fn = filename.decode().strip('\x00')
file_new_name = os.path.join(save_path, fn)
print('newname is {0}, filesize {1}'.format(file_new_name,filesize))
recvd_size = 0
fp = open(file_new_name, 'wb')
print('start receving')
while not recvd_size == filesize:
if filesize - recvd_size >1024:
data = sock.recv(1024)
recvd_size += len(data)
else:
data = sock.recv(1024)
recvd_size = filesize
fp.write(data)
fp.close()
print('Files received')
sock.close()
break
def extent_tar(save_path):
tar_path = os.walk(save_path)
for path, dir_list, file_list in tar_path:
for dir_name in file_list:
tarname = os.path.join(path, dir_name)
if os.path.splitext(tarname)[-1] == '.tar':
print('TRUE')
tar = tarfile.open(tarname, 'r:')
file_names = tar.getnames()
for file_name in file_names:
tar.extract(file_name, save_path)
tar.close()
print('tarfile extented')
os.remove(tarname)
print('tarfile deleted')
if __name__ == '__main__':
socket_service()
客户端:发送文件
import socket
import os
import sys
import struct
import tarfile
def sock_client_image():
while True:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('服务端ip地址', port))
#服务器和客户端在不同的系统或不同的主机下时使用的ip和端口
#首先要查看服务器所在的系统网卡的ip ,客户端服务端port必须相同
except socket.error as msg:
print(msg)
print(sys.exit(1))
filespath = input('发送的文件夹路径 ')
filepath = input('打包路径')
with tarfile.open(filepath,'w') as tar:
tar.add(filespath,arcname=os.path.basename(filespath))
fhead = struct.pack(b'128sq', bytes(os.path.basename(filepath), encoding='utf-8'),
os.stat(filepath).st_size)
s.send(fhead)
fp = open(filepath, 'rb')
while True:
data = fp.read(1024)
if not data:
print('{0} send over...'.format(filepath))
break
s.send(data)
fp.close()
s.close()
os.remove(filepath)
if __name__ == '__main__':
sock_client_image()
亲测在ubuntu和windos下能够实现文件夹的互传,但这种方法缺点在于每次发送文件夹都要新建一个压缩文件,对于大型文件夹来说十分不便。自己在使用时也是深有体会,本人功力尚浅,等有了更好的方法再来讨论。