TFTP_server python實現(個人備忘)

來源:互聯網
上載者:User

標籤:python實現   print   ram   ini   coding   客戶   cmd   編號   add   

#coding=utf-8
from socket import *
import time,struct
class TFTPServer():

#作業碼
DOWNLOAD = 1
UPLOAD = 2
DATA = 3
ACK = 4
ERROR = 5

def __init__(self):
self.serverSocket = socket(AF_INET, SOCK_DGRAM)
self.serverSocket.bind(("", 69))

def run(self):
while True:
print("#"*30)
print("等待用戶端串連!")
self.listen()

if self.cmdType == self.DOWNLOAD:
self.download()
elif self.cmdType == self.UPLOAD:
self.upload()

def listen(self):
# 等待client連結
self.recvData, self.recvAddr = self.serverSocket.recvfrom(1024)
self.cmdType = struct.unpack("!H", self.recvData[:2])[0]

# 用戶端請求下載
def download(self):
# 建立隨機連接埠
udpSocket = socket(AF_INET, SOCK_DGRAM)

fileReq = None
try:
# 讀取用戶端要下載的檔案名稱
fileReqName = self.recvData[2:-7].decode()
print(fileReqName)
print("用戶端請求下載檔案:%s" % fileReqName)
# 開啟檔案
try:
fileReq = open(fileReqName, "rb")
except:
print("檔案 《%s》 不存在" % fileReqName)
# 向 client 發送異常資訊
errInfo = struct.pack("!HHHb", 5, 5, 5, 0)
udpSocket.sendto(errInfo, self.recvAddr)
return False

# 初始化塊編號
frameNum = 1

while True:
fileData = fileReq.read(512)
# 打包
# frameData = struct.pack(str("!HH%ds" % len(fileData)), 3, frameNum, fileData)
frameData = struct.pack(str("!HH"), 3, frameNum) + fileData
# 發送
for i in range(0, 3):
udpSocket.sendto(frameData, self.recvAddr)

# 若檔案已發送完成
if len(fileData) < 512:
print("檔案發送完成!")
fileReq.close()
fileReq = None
return True

# 等待client響應
# 接收資料
self.recvData, self.recvAddr = udpSocket.recvfrom(1024)
cmdType, recvFrameNum = struct.unpack("!HH", self.recvData[:4])
if cmdType == self.ACK and recvFrameNum == frameNum:
break
elif i == 3:
print("連結異常,取消發送")
# 向 client 發送異常資訊
errInfo = struct.pack("!HHHb", 5, 5, 5, 0)
udpSocket.sendto(errInfo, self.recvAddr)
exit()

# 編號+1
frameNum += 1
finally:
if fileReq != None:
fileReq.close()

# 用戶端請求上傳
def upload(self):
# 建立隨機連接埠
udpSocket = socket(AF_INET, SOCK_DGRAM)

# 發送相應,確認開始接收
ack = struct.pack("!HH", self.ACK, 0)
udpSocket.sendto(ack, self.recvAddr)

# 幀計數,用於資料校正
recvFrameNum = 1
# 等待 client 資料
while True:
#接收資料
recvData, recvAddr = udpSocket.recvfrom(1024)
#資料幀: 作業碼2 快編號2 資料n
cmdType, frameNum = struct.unpack("!HH", recvData[:4])
# 判斷接收的是否是“資料”
if cmdType == self.DATA and frameNum == recvFrameNum:
print("接收到第%d幀資料!" % frameNum) # for test
# 開啟檔案
if frameNum == 1:
fileRecv = open("upload.txt", "ab")
fileRecv.write(b"#" * 30 + time.strftime("%Y-%m-%d %H:%M:%S").encode() + b"#" * 30 + b"\n")

fileRecv.write(recvData[4:])

# 響應 : 作業碼2 快編號2
ack = struct.pack("!HH", self.ACK, frameNum)
udpSocket.sendto(ack, recvAddr)

# 判斷是否發送完
if len(recvData) < 516:
fileRecv.close()
fileRecv = None
print("接收完畢, 關閉檔案。")
break

# 計數+1
recvFrameNum += 1

elif cmdType == self.ERROR:
print("用戶端串連異常,退出!")
break


server = TFTPServer()
server.run()

TFTP_server python實現(個人備忘)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.