Tftp file transfer server (based on UDP protocol)

A simple UDP server and client

Server: 

1  from socket import *
 2  #Create socket 
3 udp_server = socket(AF_INET,SOCK_DGRAM)
 4  
5 msg_server = ( "" ,8877 )
 6  #Bind ip address and port 
7  udp_server.bind(msg_server)
 8  
9  while True:
 10      #Accept the message, note that recvfrom() is used here 
11      msg_client = udp_server.recvfrom(1024 )
 12  
13      print ( "The new client is connected--->>> " )
 14  
15      if len(msg_client) !=0:
 16          # There are two values ​​in msg_client, the first one represents the content of the received message, and the second one represents the client's IP address and port information 
17          print ( " %s:%s " % (msg_client[1] , msg_client[0].decode( " utf-8 " )))
 18      else :
 19          break 
20  
21 udp_server.close()

 

Client:

from socket import *

sock = socket (AF_INET, SOCK_DGRAM)

addr_msg = ( " 192.168.1.104 " ,8877 )
 #Connect the server 
sock.connect(addr_msg)

while True:
    msg_send = input( " Please enter the message to be sent: " )
     if msg_send == ' q ' :
         break 
    #Note that sendto() is used here, where the first parameter indicates the content of the message to be sent, and the second parameter A tuple representing the IP address and port of the 
    server sock.sendto(msg_send.encode( " utf-8 " ),addr_msg)

sock.close()

 

 

UDP-based tftp file transfer

Client:

1  from socket import *
 2  import struct
 3  import os
 4  
5  def main():
 6      file_name = input( " Please enter the name of the file to download: " )
 7      #Create a UDP socket 
8      udpsocket = socket(AF_INET, SOCK_DGRAM)
 9      #Create a tftp download request H indicates that the first parameter occupies two bytes, d indicates that the corresponding parameter is bite type 
10      #   %ds indicates the number of characters occupied by the file name, such as the following octet occupies 5 characters, so it is written as 5s 
11      #   octet is a mode of tftp transmission, which determines the format of the transmitted data, and there are several other modes of tftp transmission 
12      #The package is constructed using pack in struck, where H means that the parameter occupies two bytes 
13      request_header = struct.pack( " !H%dsb5sb " %len(file_name),1,file_name,0, " octet " , 0)
 14  
15      server_msg = ( " localhost " ,8888 )
 16      #Send a request to download a file 
17      udpsocket.sendto(request_header,server_msg)
 18  
19      f = open(file_name, " w " )
 20  
21      #   num represents data The number of the block, here makes its initial value 0 
22      num = 0
 23      #Create a mark here to confirm that no errors occurred during transmission 
24      mask = True
 25  
26      while True:
 27          #Receive data packets from the server 
28          response_data = udpsocket.recvfrom(1024 )
 29          recv_data, server_info = response_data
 30  
31          #Here , use unpack in struct to unpack H, indicating that the data occupies two bytes in length 
32          #The first two bytes here store the opcode 
33          operation_num = struct.unpack( " !H " ,recv_data[: 2 ])
 34          #The third and fourth bytes here store the number of the data block 
35          package_num = struct.unpack( "!H " ,recv_data[2:4 ])
 36  
37          #When the opcode is 3, it means that the received information is a data packet sent by the server to the client after receiving the response 
38 if          operation_num [0] == 3 :
 39              #This The value received at one time should be the result of adding one to the value received last time 
40 num              += 1
 41              #This means that once the value of num exceeds the range of the value represented by its 2 bytes , then let it repeat from 0 (mainly because the opcode can only occupy 2 bytes) 42 if num == 65535 :
 43                  num = 0
 44 #Confirm the block number 45 if num == package_num[0 ]:   #The subscript is removed here because the package_num at this time represents a tuple, and the block number is the first data in the tuple 46 #Write the specific data received into the file
                          
             
                 
47                  f.write(recv_data[4 :])
 48                  #The confirmation of the block number must add 1 to the previous value each time 
49                  num = package_num[0]
 50              #Construct a response packet with an opcode of 4. The data sent is to add The block number after the last 1 
51              ack_data = struct.pack( " !HH " ,4 ,package_num[0])
 52              #Send response packet 
53              udpsocket.sendto(ack_data, server_info)
 54  
55          elif operation_num[0] == 5 :
 56              print ( " Error! " )
 57              #If an error message occurs, change the value of the tag to False so that subsequent operations can delete the file
58              mask = False
 59  
60          #The maximum length of a data packet is 4+512 = 516 bits, if the data packet is less than this value, it means that this is the last data transmission 
61          if len(recv_data) < 516 :
 62              print ( " Cmplete! " )
 63              break 
64      # The value of the mask flag is True, which means that there is no error during the file transfer, and the locally received file is closed and saved 
65      if mask == True:
 66          f.close()
 67  
68      else :
 69          # If the value of the mask flag is False, it means that there is an error message during the file transfer, then delete the received file 
70          os.remove(file_name)
 71  
72  if __name__ == "__main":
73     main()

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325061739&siteId=291194637