福州php做网站,现代网络营销的方式,seo技巧优化,为什么不自己做购物网站立即学习:https://edu.csdn.net/course/play/24458/296245?utm_sourceblogtoedu
1.课程目的#xff1a; 实现客户端输入下载文件的命令#xff0c;然后将命令发送给服务端#xff0c;服务端再执行下载文件的命令#xff0c;最后将执行下载文件命令后的结果返回给客户端blogtoedu
1.课程目的 实现客户端输入下载文件的命令然后将命令发送给服务端服务端再执行下载文件的命令最后将执行下载文件命令后的结果返回给客户端客户端进行接收这样就完成了一个简单的文件下载功能。文件的上传与下载类似只是两个相反的过程 2.知识点与关键点
1os模块可使用os.path.getsize(filename)来获取指定文件的大小
2在服务端接收的命令使用split命令将接收的命令的字符串分割判断第一个是‘get’还是‘put’即判断时下载文件还是上传文件 3.完整代码 服务端 import socket
import subprocess
import json
import struct
import os
server_dir rC:\Users\jinlin\Desktop\python_further_study\socket编程\文件的传输上传\简单版本\servephone 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:#接收客户端发送过来连接服务器请求res phone.accept()conn,client_addr reswhile True:try:#1接收客户端发送过来的命令resv conn.recv(1024)#2将接收到的结果进行分割获得命令以及文件名cmds resv.decode(utf-8).split()#[get,a.txt]print(**50)#3处理命令执行命令并且获得命令得到的结果cmd cmds[0]filename cmds[1]total_size os.path.getsize(r%s/%s%(server_dir,filename))#获得文件的字节数大小#1制作包含文件名和文件大小的文件头用字典实现headers_dict {filename:filename,filedata:2020/03/09,total_size:total_size}#2将字典先序列化成惊悚字符串再转为bytes类型文件头headers_json json.dumps(headers_dict)#3)获取bytes类型的长度headers_bytes headers_json.encode(utf-8)headers_size len(headers_bytes)#4)将bytes类型文件头长度定制为固定长度的报头header struct.pack(i,headers_size)#5)向客户端发送报头conn.send(header)#6)向客户端发送包含文件信息的字典conn.send(headers_bytes)#7)通过二进制只读的方式打开文件按行读取文件并且发送给客户端with open(filename,rb) as fp:for line in fp:conn.send(line)except ConnectionResetError:breakconn.close()phone.close()客户端 #导入模块
import socket
import struct
import json
client_dir rC:\Users\jinlin\Desktop\python_further_study\socket编程\文件的传输上传\简单版本\client#1、设置phone套接字
phone socket.socket(socket.AF_INET,socket.SOCK_STREAM)#2、连接服务器打电话,本地地址127.0.0.1
phone.connect((127.0.0.1,8080))#3、向服务器发送请求send(),发送的数据不能直接发送字符串因为要传送到物理层底层因此需要转换成二进制的bytes类型进行发送只需:发送的数据.encode(utf-8)即可
while True:cmd input(请输入)#向服务端发送下载文件的命令get a.txt#修复客户端发送空字符串而服务器卡在接收信息处的bug,continue表示跳出本次循环重新开始下一次的循环if not cmd:continuephone.send(cmd.encode(utf-8))#4、接收服务器返回来的数据recv()#1)先接收由服务器返回来的报头,报头是固定长度的因此取前面4字节的数据即为报头header phone.recv(4)#返回的是一个对象#2解析报头得到bytes类型的文件头长度obj_truple struct.unpack(i,header)#返回的是一个元组headers_bytes_size obj_truple[0]#取元组第一个元素即为总字节数#3)接收bytes类型的文件头数据headers_bytes phone.recv(headers_bytes_size)#4将bytes类型的文件头数据反序列化成字典headers_json headers_bytes.decode(utf-8)headers_dict json.loads(headers_json)print(headers_dict)#5)从字典中取出字命令执行结果字节总长度total_size headers_dict[total_size]filename headers_dict[filename]#6)接收返回的数据with open(r%s/%s%(client_dir,filename), wb) as fp:recv_size 0while recv_size total_size:recv_line phone.recv(1024)#接收小于1024bytes的数据fp.write(recv_line)recv_size len(recv_line)print(文件总字节长为%s,已经下载了%s%(total_size,recv_size))#5、关闭套接字phone
phone.close() 4.运行的结果
...
客户端结果
...
请输入get mn.png {filename: mn.png, filedata: 2020/03/09, total_size: 702935} 文件总字节长为702935,已经下载了6 文件总字节长为702935,已经下载了8 文件总字节长为702935,已经下载了237 文件总字节长为702935,已经下载了455 文件总字节长为702935,已经下载了686 文件总字节长为702935,已经下载了851 文件总字节长为702935,已经下载了946 文件总字节长为702935,已经下载了1113 文件总字节长为702935,已经下载了1339 文件总字节长为702935,已经下载了1387 文件总字节长为702935,已经下载了1847 文件总字节长为702935,已经下载了2009
.......
文件总字节长为702935,已经下载了702656 文件总字节长为702935,已经下载了702935
5.待改进
代码的可读性较差可以通过函数以及面向对象来对其进行优化增加其代码的可读性