#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 ("Wait for the client to connect!" ")
Self.listen ()
if Self.cmdtype = = self. DOWNLOAD:
Self.download ()
Elif Self.cmdtype = = self. UPLOAD:
Self.upload ()
def listen (self):
# Wait for client link
Self.recvdata, self.recvaddr = Self.serverSocket.recvfrom (1024)
Self.cmdtype = Struct.unpack ("! H ", Self.recvdata[:2]) [0]
# Client Request Download
def download (self):
# New Random Port
Udpsocket = socket (af_inet, SOCK_DGRAM)
Filereq = None
Try
# Read the file name to be downloaded by the client
Filereqname = Self.recvdata[2:-7].decode ()
Print (Filereqname)
Print ("Client request download file:%s"% filereqname)
# Open File
Try
Filereq = open (Filereqname, "RB")
Except
Print ("file%s" does not exist "% filereqname")
# Send exception information to client
Errinfo = Struct.pack ("! HHHB ", 5, 5, 5, 0)
Udpsocket.sendto (Errinfo, SELF.RECVADDR)
Return False
# Initialize block number
Framenum = 1
While True:
FileData = Filereq.read (512)
# pack
# framedata = Struct.pack (str ("! Hh%ds "% len (fileData)), 3, Framenum, FileData)
Framedata = Struct.pack (str ("! HH "), 3, framenum) + FileData
# Send
For I in range (0, 3):
Udpsocket.sendto (Framedata, SELF.RECVADDR)
# If the file has been sent complete
If Len (FileData) < 512:
Print ("File Send complete! ")
Filereq.close ()
Filereq = None
Return True
# Wait for client response
# Receive Data
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 ("link exception, Cancel send")
# Send exception information to client
Errinfo = Struct.pack ("! HHHB ", 5, 5, 5, 0)
Udpsocket.sendto (Errinfo, SELF.RECVADDR)
Exit ()
# No. +1
Framenum + = 1
Finally
If filereq! = None:
Filereq.close ()
# Client Request Upload
def upload (self):
# New Random Port
Udpsocket = socket (af_inet, SOCK_DGRAM)
# send corresponding, confirm start receiving
ACK = Struct.pack ("! HH ", self. ACK, 0)
Udpsocket.sendto (ACK, SELF.RECVADDR)
# frame count, for data validation
Recvframenum = 1
# Wait for client data
While True:
#接收数据
RecvData, recvaddr = Udpsocket.recvfrom (1024)
#数据帧: OpCode 2 Fast number 2 data n
Cmdtype, Framenum = Struct.unpack ("! HH ", Recvdata[:4])
# Determine if the received is "data"
if Cmdtype = = self. DATA and Framenum = = Recvframenum:
Print ("Received frame%d data! "% framenum) # for Test
# Open File
if framenum = = 1:
FILERECV = open ("Upload.txt", "AB")
Filerecv.write (b "#" * + time.strftime ("%y-%m-%d%h:%m:%s"). Encode () + B "#" * + + B "\ n")
Filerecv.write (recvdata[4:])
# response: OpCode 2 Fast number 2
ACK = Struct.pack ("! HH ", self. ACK, Framenum)
Udpsocket.sendto (ACK, RECVADDR)
# Determine if you are finished sending
If Len (RecvData) < 516:
Filerecv.close ()
FILERECV = None
Print ("Close the file after receiving it. ")
Break
# Count +1
Recvframenum + = 1
Elif Cmdtype = = self. ERROR:
Print ("Client connection exception, exit!") ")
Break
Server = Tftpserver ()
Server.run ()
Tftp_server Python Implementation (personal memo)