• Python UDP 协议网络编程《四》


    今日主题:使用Python 实现的下载文件的客户端功能。

    温馨提示:
    今日内容与上一篇文章Python UDP 协议网络编程《三》具有关联性,如果Python UDP 协议网络编程《三》没有阅读的小伙伴,建议先阅读后,再来学习今天的内容,有助于更好的理解哟(点击蓝色字体的推文名称即可查看上一篇文章全部内容)。

    理论内容较少,今天更偏实战性,以下实现代码需仔细分析、理解每一行代码的作用及相互间的关联关系,并自行搭建本地环境将代码运行起来,在解决问题的过程中,通过思考与实践才能更好的理解本文主题。

     1import struct
     2from socket import socket,AF_INET,SOCK_DGRAM
     3
     4filename="QR.png" #定义要下载的文件名
     5ftp_server_ip="127.0.0.1" #定义服务器的ip地址
     6
     7def download_file():
     8    print("step1:准备开始下载"+filename+"文件")
     9    send_data=struct.pack("!H%dsb5sb"%len(filename),1,filename.encode("utf-8"),0,b'octet',0) #封装一个读文件请求,上面的步骤1
    10    print("step2:建立一个udp socket连接")
    11    udp_socket=socket(AF_INET,SOCK_DGRAM) #创建一个udp socket
    12    print("step3:向tftp ip=127.0.0.1 port=69服务器发送读写请求")
    13    udp_socket.sendto(send_data,(ftp_server_ip,69)) #向tftp 服务器发送读写请求
    14    print("step4:新建一个文件句柄,为了接收想下载的文件内容")
    15    fhandle=open(filename,'ab')#在本地创建一个文件,a表示追加,b表示二进制
    16    while 1:
    17        print("step5:开始接收消息,消息内容为接收的数据和服务器信息")
    18        recv_data,server_info=udp_socket.recvfrom(1024) #接收数据,返回的是二维元组,第一个是接收的数据,第二个是服务器ip and port,上面的步骤2
    19        operation_code=struct.unpack("!H",recv_data[:2]) #获取操作码
    20        ack_num=struct.unpack("!H",recv_data[2:4]) #获取数据块
    21        print("step6: 获取操作码:", operation_code, "和数据块编号", ack_num)
    22        print("step7: 打印:the server of info is:",server_info)
    23        if operation_code==5:#5就是错误码
    24            print("the file is not found")
    25            break
    26        print("step8:打印接收的数据:",recv_data)
    27        print("step9:开始写文件")
    28        fhandle.write(recv_data[4:])#写内容到文件,因为前四个字节是操作码和数据块,所以要从第四位开始写文件
    29        print("step10:判断文件是否读取完成")
    30        if(len(recv_data)<516):#判断文件是否读取完成,上面的步骤4
    31            fhandle.close()
    32            break
    33        '''
    34        3、ACK
    35        操作码  +  块编码
    36        2Bytes     2Bytes
    37        '''#因为发布ACK包的操作码与块编码都是2个字节,所以如下用的是HH
    38        print("step10:封装确认包信息")
    39        send_data1=struct.pack("!HH",4,ack_num[0]) #封装确认包信息
    40        print("step11:获取服务器端ip and port")
    41        server_port=server_info[1]#获取服务器端发送数据的随机端口
    42        server_address=server_info[0]
    43        print("step12:发送ACK 确认包信息")
    44        udp_socket.sendto(send_data1,(server_address,server_port))#发送确认包信息,上面的步骤3
    45    print("step13:文件"+filename+"下载成功!!!")
    46
    47def user_login():
    48    udp_socket = socket(AF_INET, SOCK_DGRAM)  # 建议upd连接
    49    local_address = ('127.0.0.1', 8000)  # 定义了本机的ip and port
    50    udp_socket.bind(local_address)  # 绑定本机的ip and port
    51    resvice_address=('127.0.0.1', 69) #定义了接收消息机器的ip and port
    52    data="admin 123456"
    53    udp_socket.sendto(str(data).encode("utf-8"),resvice_address)#向接收消息机器发送消息
    54    udp_socket.close()
    55    udp_secv_msg()
    56
    57def udp_secv_msg():
    58    udp_sockets = socket(AF_INET, SOCK_DGRAM)  # 建立udp socker连接
    59    server_address = ('127.0.0.1', 70)  # 定义了服务端的ip and port
    60    udp_sockets.bind(server_address)  # 服务端绑定ip and port
    61    recv_data = udp_sockets.recvfrom(1024)  # 收数据等待
    62    print('接收的内容:', recv_data[0].decode('utf-8'))  # 显示收到的信息
    63    print('发送人的地址:', recv_data[1])  # 显示收到的信息
    64    udp_sockets.close()
    65
    66if __name__ == '__main__':
    67    #第一步登录tftp服务器
    68    user_login()
    69    #第二步是下载文件
    70    download_file()

    欢迎关注【无量测试之道】公众号,回复【领取资源】,
    Python编程学习资源干货、
    Python+Appium框架APP的UI自动化、
    Python+Selenium框架Web的UI自动化、
    Python+Unittest框架API自动化、

    资源和代码 免费送啦~
    文章下方有公众号二维码,可直接微信扫一扫关注即可。

    备注:我的个人公众号已正式开通,致力于测试技术的分享,包含:大数据测试、功能测试,测试开发,API接口自动化、测试运维、UI自动化测试等,微信搜索公众号:“无量测试之道”,或扫描下方二维码:

     添加关注,让我们一起共同成长!

  • 相关阅读:
    [Swift系列]002-基础语法
    [Swift系列]001-入门准备
    navicat连接服务器Mysql 忘记密码 ------- 查看密码
    Elasticsearch 7.10.1 尝鲜笔记
    java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy 排查解决
    nginx TCP 代理& windows傻瓜式安装
    python项目出现的问题 Microsoft Visual C++ 14.0 is required解决方法
    前端使用crypto.js进行加密
    xcopy 高级使用
    高并发解决方案-概念知识
  • 原文地址:https://www.cnblogs.com/Wu13241454771/p/13816368.html
Copyright © 2020-2023  润新知