網絡編程 tftp下載文件的編程

1、代碼python

 

 

 

 

操做碼 功能
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()          #關閉套接字
相關文章
相關標籤/搜索