本文實例為大家分享了python實現簡單tftp的具體代碼,供大家參考,具體內容如下
tftp服務器簡單實現:
from threading import Threadfrom socket import *import structdef upload(filename,user_ip,user_port): num = 0 f = open(filename,'ab') s_up = socket(AF_INET,SOCK_DGRAM) send_data_1 = struct.pack("!HH",4,num) s_up.sendto(send_data_1,(user_ip,user_port)) #第一次用隨機端口發送 while True: recv_data,user_info = s_up.recvfrom(1024) #第二次客戶連接我隨機端口 caozuohao_up,ack_num = struct.unpack('!HH',recv_data[:4]) print(caozuohao_up,ack_num,num) if int(caozuohao_up) == 3 and ack_num == num : f.write(recv_data[4:]) send_data = struct.pack("!HH",4,num) s_up.sendto(send_data,(user_ip,user_port)) #第二次我用隨機端口發 num = num + 1 if len(recv_data) < 516: print(user_ip+'上傳文件'+filename+':完成') f.close() exit() def download(filename,user_ip,user_port): s_down = socket(AF_INET, SOCK_DGRAM) num = 0 try: f = open(filename,'rb') except: error_data = struct.pack('!HHHb',5,5,5,num) s_down.sendto(error_data, (user_ip,user_port)) #文件不存在時發送 exit() #只會退出此線程 while True: read_data = f.read(512) send_data = struct.pack('!HH',3,num) + read_data s_down.sendto(send_data, (user_ip,user_port)) #數據第一次發送 if len(read_data) < 512: print('傳輸完成, 對方下載成功') exit() recv_ack = s_down.recv(1024) #第二次接收 caozuoma,ack_num = struct.unpack("!HH", recv_ack)# print(caozuoma,ack_num,len(read_data)) num += 1 if int(caozuoma) != 4 or int(ack_num) != num-1 : exit() f.close()s = socket(AF_INET,SOCK_DGRAM)s.bind(('',69))def main(): while 1: recv_data,(user_ip,user_port) = s.recvfrom(1024) #第一次客戶連接69端口 print(recv_data, user_ip, user_port) if struct.unpack('!b5sb',recv_data[-7:]) == (0, b'octet', 0): caozuoma = struct.unpack('!H',recv_data[:2]) filename = recv_data[2:-7].decode('gb2312') if caozuoma[0] == 1: print('對方想下載數據',filename) t = Thread(target = download, args = (filename,user_ip,user_port)) t.start() elif caozuoma[0] == 2: print('對方想上傳數據',filename) t = Thread(target = upload, args = (filename,user_ip,user_port)) t.start() if __name__ == '__main__': main()
上傳數據簡單實現:
#!/usr/bin/env python3#coding=utf-8import structfrom socket import *server_ip = '192.168.119.157'send_data_1 = struct.pack('!H8sb5sb',2,'王輝.jpg'.encode('gb2312'),0,b'octet',0)s = socket(AF_INET,SOCK_DGRAM)s.sendto(send_data_1,(server_ip,69)) #第一次發給服務器69端口f = open('王輝.jpg','rb')recv_data = s.recvfrom(1024) #第一次接收數據rand_port = recv_data[1][1]print()ack_num = struct.unpack("!HH",recv_data[0][:4])num = 0while True: read_data = f.read(512) send_data = struct.pack('!HH',3,num) + read_data s.sendto(send_data,(server_ip,rand_port)) #第二次發給服務器的隨機端口 recv_data_2,userinfo = s.recvfrom(1024) print(recv_data_2) ack_num = struct.unpack('!H',recv_data_2[2:4]) print(len(read_data),num,ack_num[0],rand_port) if len(read_data) < 512 or ack_num[0] != num : break num = num + 1
新聞熱點
疑難解答