Python UDP 协议网络编程《六》
今日主题:Python 实现的使用命令行进行文件下载的功能。
温馨提示:
今日内容与前期推文Python UDP 协议网络编程《四》具有一定的关联性,是在该文章的基础上进行的再一次改造。如果Python UDP 协议网络编程《四》没有阅读的小伙伴,建议先阅读后,再来学习今天的内容,会有一个比较直观的对比。(点击蓝色字体的推文名称即可查看上一篇文章全部内容)。
今日分享内容与已分享的Python UDP 协议网络编程系列推文一样,理论内容较少,今天更偏实战性,以下实现代码需仔细分析、理解每一行代码的作用及相互间的关联关系,可与Python UDP 协议网络编程《四》实现的功能进行对比,相信你会发现其中的不同。
同时建议小伙伴们自行搭建本地环境将代码运行起来,在解决问题的过程中,通过思考与实践才能更好的理解本文主题。
1import sys 2import struct 3from socket import socket,AF_INET,SOCK_DGRAM 4 5filename=""#定义要下载的文件名 6ftp_server_ip=""#定义服务器的ip地址 7username=""#用户名 8password=""#密码 9 10def run_cmd(): 11 global filename,ftp_server_ip,username,password 12 if(len(sys.argv)!=3): 13 print("命令行格式不对,请参照以下标准") 14 print("="*100) 15 print("for example:") 16 print() 17 print("python python_tftp_download.py username:password@ftp_server_ip filename") 18 print("=" * 100) 19 exit() 20 else: 21 filename=sys.argv[2] 22 all=sys.argv[1] 23 username=str(all).split(":")[0] 24 password=str(all).split("@")[0].split(":")[1] 25 ftp_server_ip=str(all).split("@")[1] 26 print(ftp_server_ip) 27 28def download_file(): 29 print("step1:准备开始下载"+filename+"文件") 30 send_data=struct.pack("!H%dsb5sb"%len(filename),1,filename.encode("utf-8"),0,b'octet',0) #封装一个读文件请求,上面的步骤1 31 print("step2:建立一个udp socket连接") 32 udp_socket=socket(AF_INET,SOCK_DGRAM) #创建一个udp socket 33 print("step3:向tftp ip=127.0.0.1 port=69服务器发送读写请求") 34 udp_socket.sendto(send_data,(ftp_server_ip,69)) #向tftp 服务器发送读写请求 35 print("step4:新建一个文件句柄,为了接收想下载的文件内容") 36 fhandle=open(filename,'ab')#在本地创建一个文件,a表示追加,b表示二进制 37 while 1: 38 print("step5:开始接收消息,消息内容为接收的数据和服务器信息") 39 recv_data,server_info=udp_socket.recvfrom(1024) #接收数据,返回的是二维元组,第一个是接收的数据,第二个是服务器ip and port,上面的步骤2 40 operation_code=struct.unpack("!H",recv_data[:2]) #获取操作码 41 ack_num=struct.unpack("!H",recv_data[2:4]) #获取数据块 42 print("step6: 获取操作码:", operation_code, "和数据块编号", ack_num) 43 print("step7: 打印:the server of info is:",server_info) 44 if operation_code==5:#5就是错误码 45 print("the file is not found") 46 break 47 print("step8:打印接收的数据:",recv_data) 48 print("step9:开始写文件") 49 fhandle.write(recv_data[4:])#写内容到文件,因为前四个字节是操作码和数据块,所以要从第四位开始写文件 50 print("step10:判断文件是否读取完成") 51 if(len(recv_data)<516):#判断文件是否读取完成,上面的步骤4 52 fhandle.close() 53 break 54 ''' 55 3、ACK 56 操作码 + 块编码 57 2Bytes 2Bytes 58 '''#因为发布ACK包的操作码与块编码都是2个字节,所以如下用的是HH 59 print("step10:封装确认包信息") 60 send_data1=struct.pack("!HH",4,ack_num[0]) #封装确认包信息 61 print("step11:获取服务器端ip and port") 62 server_port=server_info[1]#获取服务器端发送数据的随机端口 63 server_address=server_info[0] 64 print("step12:发送ACK 确认包信息") 65 udp_socket.sendto(send_data1,(server_address,server_port))#发送确认包信息,上面的步骤3 66 print("step13:文件"+filename+"下载成功!!!") 67 68def user_login(data): 69 udp_socket = socket(AF_INET, SOCK_DGRAM) # 建议upd连接 70 local_address = ('127.0.0.1', 8001) # 定义了本机的ip and port 71 udp_socket.bind(local_address) # 绑定本机的ip and port 72 resvice_address=('127.0.0.1', 69) #定义了接收消息机器的ip and port 73 udp_socket.sendto(str(data).encode("utf-8"),resvice_address)#向接收消息机器发送消息 74 print("登录成功") 75 udp_socket.close() 76 udp_secv_msg() 77 78def udp_secv_msg(): 79 print("开始接收消息") 80 udp_sockets = socket(AF_INET, SOCK_DGRAM) # 建立udp socker连接 81 server_address = (ftp_server_ip, 70) # 定义了服务端的ip and port 82 udp_sockets.bind(server_address) # 服务端绑定ip and port 83 print("正在接收消息") 84 recv_data = udp_sockets.recvfrom(1024) # 收数据等待 85 print("the data is:",recv_data) 86 print('接收的内容:', recv_data[0].decode('utf-8')) # 显示收到的信息 87 print('发送人的地址:', recv_data[1]) # 显示收到的信息 88 udp_sockets.close() 89 90if __name__ == '__main__': 91 #命令格式校验 92 run_cmd() 93 data = username+" "+password 94 print(data) 95 #第一步登录tftp服务器 96 user_login(data) 97 #第二步是下载文件 98 download_file()
执行结果为:
1 执行的结果为: 2 (venv) D:\BaiduNetdiskDownload\ows-project\wechat\docker-compose1>python pythonFFTP_download_command.py admin:123456@127.0.0.1 requirements.txt 3 127.0.0.1 4 admin 123456 5 登录成功 6 开始接收消息 7 正在接收消息 8 the data is: (b'\xe7\x99\xbb\xe5\xbd\x95\xe6\x88\x90\xe5\x8a\x9f,\xe5\x8f\xaf\xe4\xbb\xa5\xe5\xbc\x80\xe5\xa7\x8b\xe4\xb8\x8a\xe4\xbc\xa0\xe4\xb8\x8b\xe8\xbd\xbd\x 9 e6\x96\x87\xe4\xbb\xb6\xe4\xba\x86\xef\xbc\x81\xef\xbc\x81\xef\xbc\x81', ('127.0.0.1', 8000)) 10 接收的内容: 登录成功,可以开始上传下载文件了!!! 11 发送人的地址: ('127.0.0.1', 8000) 12 step1:准备开始下载requirements.txt文件 13 step2:建立一个udp socket连接 14 step3:向tftp ip=127.0.0.1 port=69服务器发送读写请求 15 step4:新建一个文件句柄,为了接收想下载的文件内容 16 step5:开始接收消息,消息内容为接收的数据和服务器信息 17 step6: 获取操作码: (3,) 和数据块编号 (0,) 18 step7: 打印:the server of info is: ('127.0.0.1', 64495) 19 step8:打印接收的数据: b'\x00\x03\x00\x00flask\r\nredis\r\npymysqlflask\r\nredis\r\npymysql' 20 step9:开始写文件 21 step10:判断文件是否读取完成 22 step13:文件requirements.txt下载成功!!!
欢迎关注【无量测试之道】公众号,回复【领取资源】,
Python编程学习资源干货、
Python+Appium框架APP的UI自动化、
Python+Selenium框架Web的UI自动化、
Python+Unittest框架API自动化、
资源和代码 免费送啦~
文章下方有公众号二维码,可直接微信扫一扫关注即可。
备注:我的个人公众号已正式开通,致力于测试技术的分享,包含:大数据测试、功能测试,测试开发,API接口自动化、测试运维、UI自动化测试等,微信搜索公众号:“无量测试之道”,或扫描下方二维码:
添加关注,让我们一起共同成长!