python实现简单tftp(基于udp)

- tftp是基于udp的协议
- 实现简单的tftp,首先要有tftp的协议图。
- tftp默认接收端口为69,但每次有连接过来后,tftp会随机分配一个端口来专门为这个连接来服务。
- 操作码:1.上传 2.下载 3.传数据 4.接收确认 5.错误码
tftp服务器简单实现:
from threading import Thread
from socket import *
import struct def 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-8 import struct
from 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 = 0
while 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
下载数据简单实现:
#!/usr/bin/env python3
#coding=utf-8 import struct
from socket import * filename = 'test.jpg'
server_ip = '192.168.1.113' send_data = struct.pack('!H%dsb5sb'%len(filename),1,filename.encode('gb2312'),0,'octet'.encode('gb2312'),0)
s = socket(AF_INET,SOCK_DGRAM)
s.sendto(send_data,(server_ip,69)) #第一次发送, 连接服务器69端口 f = open(filename,'ab') while 1:
recv_data = s.recvfrom(1024) #接收数据
caozuoma,ack_num = struct.unpack('!HH',recv_data[0][:4]) #获取数据块编号
rand_port = recv_data[1][1] #获取服务器的随机端口 if int(caozuoma) == 5:
print('服务器返回: 文件不存在...')
break
print(caozuoma,ack_num,rand_port,len(recv_data[0])) f.write(recv_data[0][4:])
if len(recv_data[0]) < 516:
break ack_data = struct.pack("!HH",4,ack_num)
s.sendto(ack_data,(server_ip,rand_port)) #回复ACK确认包
python实现简单tftp(基于udp)的更多相关文章
- Python中的端口协议之基于UDP协议的通信传输
UDP协议: 1.python中基于udp协议的客户端与服务端通信简单过程实现 2.udp协议的一些特点(与tcp协议的比较) 3.利用socketserver模块实现udp传输协议的并 ...
- Python网络编程02 /基于TCP、UDP协议的socket简单的通信、字符串转bytes类型
Python网络编程02 /基于TCP.UDP协议的socket简单的通信.字符串转bytes类型 目录 Python网络编程02 /基于TCP.UDP协议的socket简单的通信.字符串转bytes ...
- UNIX网络编程——分析一帧基于UDP的TFTP协议帧
下图是UDP的段格式: 相比TCP段格式,UDP要简单得多,也没啥好说的,需要注意的是UDP数据长度指payload加上首部的长度. 下面分析一帧基于UDP的TFTP协议帧: 以太网首部 0000: ...
- python 全栈开发,Day34(基于UDP协议的socket)
昨日内容回顾 网络的基础概念arp协议 :通过ip地址找到mac地址五层模型 : 应用层 传输层 网络层 数据链路层 物理层tcp协议 : 可靠的 面向连接 全双工 三次握手 四次挥手udp协议 : ...
- 分析一帧基于UDP的TFTP协议帧
下图是UDP的段格式: 相比TCP段格式,UDP要简单得多,也没啥好说的,需要注意的是UDP数据长度指payload加上首部的长度. 下面分析一帧基于UDP的TFTP协议帧: 以太网首部 0000: ...
- Tftp文件传输服务器(基于UDP协议)
一个简单的UDP服务端与客户端 服务端: from socket import * #创建套接字 udp_server = socket(AF_INET,SOCK_DGRAM) msg_server ...
- 基于udp简单聊天的系统
老师博客:http://www.cnblogs.com/Eva-J/articles/8244551.html#_label4 基于udp的简单的聊天代码 说明:这段代码,显示有client向serv ...
- Websocket - Websocket原理(握手、解密、加密)、基于Python实现简单示例
一.Websocket原理(握手.解密.加密) WebSocket协议是基于TCP的一种新的协议.WebSocket最初在HTML5规范中被引用为TCP连接,作为基于TCP的套接字API的占位符.它实 ...
- linux网络编程之用socket实现简单客户端和服务端的通信(基于UDP)
单客户端和服务端的通信(基于UDP) 代码 服务端代码socket3.c #include<sys/types.h> #include<sys/socket.h> #inc ...
随机推荐
- springboot入门的一点基础
什么是SpringBoot java问世20年由于,发展到现在从技术角度来说已经很成熟,开发过程中我们总是在想如何去提高团队开发规范性.减少重复配置.避免低效开发.部署发布时流程的复杂度以及第三方技术 ...
- 【BZOJ4372】烁烁的游戏(动态点分治)
[BZOJ4372]烁烁的游戏(动态点分治) 题面 BZOJ 大意: 每次在一棵书上进行操作 1.将离某个点u的距离不超过d的点的权值加上w 2.询问单点权值 题解 这题和前面那一道震波几乎是一模一样 ...
- PKUWC2018游记
PKUWC2018游记 Day -inf 从去年的12月底开始停课,到现在也有整整一个月的时间了. 前两周考的是OI赛制,后来就变成了IOI赛制. 整体上考的很炸,虐场的次数远少于被虐的次数. 关于去 ...
- POJ3261:Milk Patterns
题面 vjudge Sol 二分答案+分组,判断有没有一个组的后缀个数不小于 k 做法 # include <bits/stdc++.h> # define IL inline # def ...
- iOS逆向工程,(狗神)沙梓社大咖免费技术分享。
序言 简介:本文针对于广大iOS开发者,作为一名开发者,仅仅专注于一门语言可能已经不适用现在的市场需求,曾经因高薪和需求量巨大,而火爆一时的移动端开发者(Android,ios),如今的路却是不再那么 ...
- python socket知识点
---恢复内容开始--- 数据在网络上进行传播,需要通过一种通信协议.常见的通信协议有:HTTP,SMTP,DNS,FTP,SSH,SNMP,ICMP PING,DNCP. OSI(Open Syst ...
- python 全栈开发,Day2
python基础二(基础数据类型) 一.数据 1 什么是数据? x=10,10是我们要存储的数据 2 为何数据要分不同的类型 数据是用来表示状态的,不同的状态就应该用不同的类型的数据去表示 3 数据类 ...
- Java设计模式(二)抽象工厂模式
一.场景描述 接<Java设计模式(一)工厂模式>https://www.cnblogs.com/mahongbiao/p/8618970.html 工厂模式有一缺点,就是破坏了类的封闭性 ...
- Android 零散知识点整理
Android 零散知识点整理 为什么Android的更新试图操作必须在主线程中进行? 这是因为Android系统中的视图组件并不是线程安全的.通常应该让主线程负责创建.显示和更新UI,启动子线程,停 ...
- [总结] O(n)求和为0的最长子段
以这题为例 Solution 我们首先用前缀和差分,可以认为G是1,R是-1,然后求一个前缀和qzh. 如果 qzh[i]==qzh[j] 那么 i~j 这一整段,一定是一个和为0的区间,即红绿相等的 ...