网络编程-文件传输
功能实现:
server:
import socket,os import subprocess import struct import json import os share_dir=r"E:\Code\PyCharm\Luf\Chapter06-网络编程\09_文件上传下载\server\share" phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) phone.bind(('127.0.0.1',8080)) phone.listen(5) while True: conn,client_addr=phone.accept() print(client_addr) while True: try: #1、接收命令 res=conn.recv(8096) if not res: break #2、解析命令,提取相应命令参数 cmds=res.decode("utf-8").split() filename=cmds[1] file_full_path=os.path.join(share_dir,filename) #第一步,制作固定长度的报头 header_dic={ 'filename':filename, 'md5':1, 'file_size':os.path.getsize(file_full_path) } header_bytes=json.dumps(header_dic).encode("utf-8") header=struct.pack('i',len(header_bytes)) #第二步,先发送报头的长度 conn.send(header) #第三步,发送报头 conn.send(header_bytes) #第四步,发送真实数据 # 3、以读的方式打开文件,读取文件内容,发送给客户端 with open(file_full_path, 'rb') as f: for line in f: conn.send(line) print("send file is end") except ConnectionResetError: break conn.close()#连接关闭 phone.close()#套接字关闭
client:
import socket # client=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # client.connect(('127.0.0.1',8080)) # client.send('hello'.encode('gbk')) # client.send('world'.encode('gbk')) # # while True: # # #1、发送命令 # # cmd=input('>> ').strip() # # if not cmd:continue # # client.send(cmd.encode('gbk')) # # #2、拿到结果并打印 # # data=client.recv(1024).decode('gbk')#1024是坑 # # print(data) # client.close() import socket import struct import json import os download_dir=r"E:\Code\PyCharm\Luf\Chapter06-网络编程\09_文件上传下载\client\download" client=socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect(('127.0.0.1',8080)) #通信循环 while True: #1、发送命令 cmd=input('>> ').strip()#get a.txt if not cmd:continue#避免用户输入空字符串导致客户端卡死 client.send(cmd.encode('utf-8')) #1、先拿到数据长度(包头),取得有效数据 header=client.recv(4) header_size=struct.unpack('i',header)[0] #2、接收报头 print(header_size) header_bytes=client.recv(header_size) #3、从报头中获取有用数据 header_json=header_bytes.decode('utf-8') print(header_json) header_dic=json.loads(header_json) total_size=header_dic['file_size'] filename=os.path.join(download_dir,header_dic['filename']) #打开文件写入内容 with open(filename,'wb') as f: recv_size = 0 while recv_size < total_size: line=client.recv(1024) f.write(line) recv_size+=len(line) print("总大小:%s 已下载:%s" % (total_size,recv_size)) #关闭连接 client.close()
函数版本实现文件传输:
server:
import socket,os import subprocess import struct import json import os share_dir=r"E:\Code\PyCharm\Luf\Chapter06-网络编程\09_文件上传下载\server\share" def get(conn,cmds): filename = cmds[1] file_full_path = os.path.join(share_dir, filename) # 第一步,制作固定长度的报头 header_dic = { 'filename': filename, 'md5': 1, 'file_size': os.path.getsize(file_full_path) } header_bytes = json.dumps(header_dic).encode("utf-8") header = struct.pack('i', len(header_bytes)) # 第二步,先发送报头的长度 conn.send(header) # 第三步,发送报头 conn.send(header_bytes) # 第四步,发送真实数据 # 3、以读的方式打开文件,读取文件内容,发送给客户端 with open(file_full_path, 'rb') as f: for line in f: conn.send(line) print("send file is end") def run(): phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) phone.bind(('127.0.0.1',8080)) phone.listen(5) while True: conn,client_addr=phone.accept() print(client_addr) while True: try: #1、接收命令 res=conn.recv(8096) if not res: break #2、解析命令,提取相应命令参数 cmds=res.decode("utf-8").split() if cmds[0]=='get': get(conn,cmds) except ConnectionResetError: break conn.close()#连接关闭 phone.close()#套接字关闭 run()
client:
import socket import struct import json import os download_dir=r"E:\Code\PyCharm\Luf\Chapter06-网络编程\09_文件上传下载\client\download" def get(client): # 1、先拿到数据长度(包头),取得有效数据 header = client.recv(4) header_size = struct.unpack('i', header)[0] # 2、接收报头 header_bytes = client.recv(header_size) # 3、从报头中获取有用数据 header_json = header_bytes.decode('utf-8') header_dic = json.loads(header_json) total_size = header_dic['file_size'] filename = os.path.join(download_dir, header_dic['filename']) # 打开文件写入内容 with open(filename, 'wb') as f: recv_size = 0 while recv_size < total_size: line = client.recv(1024) f.write(line) recv_size += len(line) print("总大小:%s 已下载:%s" % (total_size, recv_size)) def run(): client=socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect(('127.0.0.1',8080)) #通信循环 while True: #1、发送命令 cmd=input('>> ').strip()#get a.txt if not cmd:continue#避免用户输入空字符串导致客户端卡死 client.send(cmd.encode('utf-8')) cmds=cmd.split() if cmds[0]=="get": get(client) #关闭连接 client.close() run()
面向对象版本: