前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python UDP 协议网络编程《六》

Python UDP 协议网络编程《六》

作者头像
Wu_Candy
发布2022-07-04 19:53:21
4370
发布2022-07-04 19:53:21
举报
文章被收录于专栏:无量测试之道

作者 | 无量测试之道 编辑 | 小 晴

今天继续和大家分享Python UDP 协议网络编程系列知识。

今日主题:Python 实现的使用命令行进行文件下载的功能。

温馨提示: 今日内容与前期推文Python UDP 协议网络编程《四》具有一定的关联性,是在该文章的基础上进行的再一次改造。如果Python UDP 协议网络编程《四》没有阅读的小伙伴,建议先阅读后,再来学习今天的内容,会有一个比较直观的对比。(点击蓝色字体的推文名称即可查看上一篇文章全部内容)。

今日分享内容与已分享的Python UDP 协议网络编程系列推文一样,理论内容较少,今天更偏实战性,以下实现代码需仔细分析、理解每一行代码的作用及相互间的关联关系,可与Python UDP 协议网络编程《四》实现的功能进行对比,相信你会发现其中的不同。

同时建议小伙伴们自行搭建本地环境将代码运行起来,在解决问题的过程中,通过思考与实践才能更好的理解本文主题。

代码语言:javascript
复制
 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()
代码语言:javascript
复制
 1执行的结果为:
 2(venv) D:\BaiduNetdiskDownload\ows-project\wechat\docker-compose1>python pythonFFTP_download_command.py admin:123456@127.0.0.1 requirements.txt
 3127.0.0.1
 4admin 123456
 5登录成功
 6开始接收消息
 7正在接收消息
 8the 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
 9e6\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)
12step1:准备开始下载requirements.txt文件
13step2:建立一个udp socket连接
14step3:向tftp ip=127.0.0.1 port=69服务器发送读写请求
15step4:新建一个文件句柄,为了接收想下载的文件内容
16step5:开始接收消息,消息内容为接收的数据和服务器信息
17step6: 获取操作码: (3,) 和数据块编号 (0,)
18step7: 打印:the server of info is: ('127.0.0.1', 64495)
19step8:打印接收的数据: b'\x00\x03\x00\x00flask\r\nredis\r\npymysqlflask\r\nredis\r\npymysql'
20step9:开始写文件
21step10:判断文件是否读取完成
22step13:文件requirements.txt下载成功!!!
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 无量测试之道 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档