一、上传的步骤
1.在服务器上创建一个空文件
2.打开本地文件读取内容
3.将内容分批传给服务器
4.传输完成,关闭文件操作
二、下载的步骤
1.在本地上创建一个空文件
2.向服务器发送读取请求
3.服务器将内容分批传给本地
4.传输完成,关闭文件操作
三、TFTP(简单文件传输协议)
1.由本地向服务器发起读写请求
2.收发数据包
3.ACK确认
4.ERROR错误信息
四、实现代码
from socket import *
import struct
server_ip = ""
#创建udp
def create_socket():
udps = socket(AF_INET, SOCK_DGRAM)
return udps
#文件读写
def file_operate(udps,type):
file_name = input("请输入需要操作的文件路径")
if type == 1:
operate_file = open(file_name, "ab")
else:
operate_file = open(file_name, "rb")
tftp(udps,type,file_name,operate_file)
operate_file.close()
#实现tftp协议
def tftp(udps,type,file_name,operate_file):
pak = struct.pack("!H6sb5sb", type, file_name.encode("utf-8"), 0, b"octet", 0)
addr = (server_ip, 69)
udps.sendto(pak, addr)#向服务器发送读写请求
while True:
content = udps.recvfrom(516)#接收服务器返回的确认信息
if type == 1:#tftp下载
ret = struct.unpack("!HH", content[0][:4])#二元元组,[0]服务器操作码信息加512字节数据(3:数据包,4:ACK,5:ERROR),[1]块编码
operate_file.write(content[0][4:])#若操作码不为5,则写入数据(此处判断省略)
ack_pak = struct.pack("!HH", 4, ret[1])
udps.sendto(ack_pak, content[1])#向服务器发送ACK确认信息
if len(content[0]) < 516:#当服务器返回的确认信息小于516个字节时,即为传输完毕
break
else:#tftp上传
ret = struct.unpack("!HH", content[0])#同下载的ret变量
upc = operate_file.read(512)#若操作码不为5,则读取最大512字节数据用于发送
data_pak = struct.pack("!HH512s", 3, ret[1] + 1, upc)#打包上传信息,块编码需自增1
udps.sendto(data_pak, content[1])#向服务器发送文件数据
if len(upc) < 512:#当文件读取内容不足512字节时,即为传输完毕
break
if __name__ == '__main__':
global server_ip
server_ip = input("请输入服务器ip:")
tp_type = int(input("请选择传输类型(下载:1,上传:2):"))
udps = create_socket()
file_operate(udps,tp_type)