网络编程 tftp下载文件的编程

一、代码

 

操作码 功能
1 读请求,即下载
2 写请求,即上传
3 表示数据包,即DATA
4 确认码,即ACK
5 错误

from socket import *
import struct
s=socket(AF_INET,SOCK_DGRAM)                                  #创建一个udp的套接字

data=struct.pack("!H5sb5sb",1,b"1.png",0,b"octet",0)
#按照TFTP数据包的格式,构造读写请求。"!"表示网络传输;H表示2个字节;s表示字符类;b表示 byte类型;数字表示重复几次。
#octet表示八进制,此处固定写法。
#   b"字符串"  转化为byte

s.sendto(data,("192.168.249.55",69))     #将构造的TFTP数据包发送到TFTP服务器上69端口。
fp=open("/home/python/tupian1.png","wb")  #在本机上打开并建立一个新文件
while(True):
    data=s.recvfrom(1024)
    print("从ip号%s,端口号%d的主机接受到数据:"%(data[1][0],data[1][1]))
    #接收来的data为一个元组,data=(data[0],(data[1][0],data[1][1])),data[0]表示516个字节的数据报,后面的是服务器发送数据报的ip地址和端口号。
    #接收的TFTP数据报大小为516个字节,其中前2个字节表示操作码,往后2个字节表示数据报序号,后面的512个字节表示数据报数据。
    op_bl= struct.unpack("!HH",data[0][:4])         #解包操作,data[0]表示TFTP的516个字节,data[0][:4]表示操作码和块编号。
    _data=data[0][4:]                #data[0][4:]   表示数据包的数据,占512byte
    if(op_bl[0]==5):                 #当操作码等于5的时候,表示错误
        print("出差错,差错码是%d,"%op_bl[1])
    elif op_bl[0]==3:                       #当操作码等于3的时候,表示数据包
        data_ack=struct.pack("!HH",4,op_bl[1])     #形成ACK,4表示操作码,op_bl[1]表示块编号
        fp.write(_data)                 #将块数据部分写入新文档
        if len(data[0]) < 516:          #当数据包内容小于516时表示文件已经传输完毕
            s.sendto(data_ack, ("192.168.249.55", data[1][1]))           #将ACK回复服务器
            break
        else:
            s.sendto(data_ack, ("192.168.249.55", data[1][1]))
    else:
        print("异常")
fp.close()        #关闭文档
s.close()          #关闭套接字

猜你喜欢

转载自www.cnblogs.com/ql0302/p/10454646.html
今日推荐