TFTP_client python实现(个人备忘)
2018-06-18 03:25:19来源:未知 阅读 ()
#coding=utf-8
from socket import *
import time,struct
class TFTPClient():
# 操作码
DOWNLOAD = 1
UPLOAD = 2
DATA = 3
ACK = 4
ERROR = 5
def __init__(self, ip = "192.168.38.1", port = 69):
self.udpSocket = socket(AF_INET, SOCK_DGRAM)
# 服务器信息
self.serverAddr = (ip, port)
def download(self, fileName):
self.udpSocket = socket(AF_INET, SOCK_DGRAM)
# fileName must be bytes
fileName = fileName.encode()
# 发送下载请求
req = struct.pack(str("!H%dsb5sb" % len(fileName)), 1, fileName, 0, b"octet", 0)
self.udpSocket.sendto(req, self.serverAddr)
print("客户端启动!请求下载文件:%s" % fileName)
#帧计数,用于数据校验
recvFrameNum = 1
try :
#等待服务器发送数据
while True:
#接收数据
recvData, recvAddr = self.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("download.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)
self.udpSocket.sendto(ack, recvAddr)
#判断是否发送完
if len(recvData) < 516 :
fileRecv.close()
fileRecv = None
print("接收完毕, 关闭文件。")
break
#计数+1
recvFrameNum += 1
elif cmdType == self.ERROR:
print("服务器返回异常,退出!")
break
finally:
if fileRecv != None:
fileRecv.close()
def upload(self, fileName):
# 若此处不新建套接字,当重复使用时会出现异常
self.udpSocket = socket(AF_INET, SOCK_DGRAM)
# fileReq = None
# fileName must be bytes
fileName = fileName.encode()
# 发送上传请求
req = struct.pack(str("!H%dsb5sb" % len(fileName)), self.UPLOAD, fileName, 0, b"octet", 0)
self.udpSocket.sendto(req, self.serverAddr)
print("客户端启动!请求上传!")
# 等待服务器就绪
recvData, recvAddr = self.udpSocket.recvfrom(1024)
cmdType, frameNum = struct.unpack("!HH", recvData[:4])
if cmdType != self.ACK or frameNum != 0:
print("服务器相应失败!")
return False
try:
# fileReqName = self.recvData[2:-7].decode()
print("客户端请求上传文件:%s" % fileName)
# 打开文件
try:
fileUpload = open(fileName, "rb")
except:
print("文件 《%s》 不存在" % fileName)
# 向 client 发送异常信息
errInfo = struct.pack("!HHHb", 5, 5, 5, 0)
self.udpSocket.sendto(errInfo, recvAddr)
return False
# 初始化块编号
frameNum = 1
while True:
fileData = fileUpload.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):
self.udpSocket.sendto(frameData, recvAddr)
# 若文件已发送完成
if len(fileData) < 512:
print("文件发送完成!")
fileUpload.close()
fileUpload = None
return True
# 等待 server 响应
# 接收数据
recvData, recvAddr = self.udpSocket.recvfrom(1024)
cmdType, recvFrameNum = struct.unpack("!HH", recvData[:4])
if cmdType == self.ACK and recvFrameNum == frameNum:
break
elif i == 3:
print("链接异常,取消发送")
# 向 client 发送异常信息
errInfo = struct.pack("!HHHb", 5, 5, 5, 0)
self.udpSocket.sendto(errInfo, recvAddr)
exit()
# 编号+1
frameNum += 1
finally:
if fileUpload != None:
fileUpload.close()
#文件名
# fileName = b"text.txt"
client = TFTPClient()
client.download("text.txt")
client.upload("text.txt")
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:格式化输出
下一篇:学习python的第一天
- python3基础之“术语表(2)” 2019-08-13
- python3 之 字符串编码小结(Unicode、utf-8、gbk、gb2312等 2019-08-13
- Python3安装impala 2019-08-13
- 小白如何入门 Python 爬虫? 2019-08-13
- python_字符串方法 2019-08-13
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash