python实现简单tftp(基于udp协议)


Posted in Python onJuly 30, 2018

本文实例为大家分享了python实现简单tftp的具体代码,供大家参考,具体内容如下

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 相关文章推荐
Python中for循环和while循环的基本使用方法
Aug 21 Python
Python3实现简单可学习的手写体识别(实例讲解)
Oct 21 Python
python调用tcpdump抓包过滤的方法
Jul 18 Python
python dict 相同key 合并value的实例
Jan 21 Python
使用PyInstaller将Pygame库编写的小游戏程序打包为exe文件及出现问题解决方法
Sep 06 Python
django中media媒体路径设置的步骤
Nov 15 Python
基于python调用psutil模块过程解析
Dec 20 Python
python实现图像全景拼接
Mar 27 Python
用python写爬虫简单吗
Jul 28 Python
python regex库实例用法总结
Jan 03 Python
python爬取新闻门户网站的示例
Apr 25 Python
Pytorch中expand()的使用(扩展某个维度)
Jul 15 Python
Python实现处理逆波兰表达式示例
Jul 30 #Python
python实现自动网页截图并裁剪图片
Jul 30 #Python
python中redis查看剩余过期时间及用正则通配符批量删除key的方法
Jul 30 #Python
对PyTorch torch.stack的实例讲解
Jul 30 #Python
Python 中字符串拼接的多种方法
Jul 30 #Python
TensorFlow Session会话控制&amp;Variable变量详解
Jul 30 #Python
TensorFlow Session使用的两种方法小结
Jul 30 #Python
You might like
php小技巧 把数组的键和值交换形成了新的数组,查找值取得键
2011/06/02 PHP
php返回json数据函数实例
2014/10/09 PHP
php语言注释,单行注释和多行注释
2018/01/21 PHP
Laravel框架中缓存的使用方法分析
2019/09/06 PHP
ThinkPHP5.1的权限控制怎么写?分享一个AUTH权限控制
2021/03/09 PHP
javascript学习笔记(三) String 字符串类型介绍
2012/06/19 Javascript
javascript实现存储hmtl字符串示例
2014/04/25 Javascript
分享一个自己动手写的jQuery分页插件
2014/08/28 Javascript
JQuery选择器绑定事件及修改内容的方法
2015/01/23 Javascript
学习vue.js条件渲染
2016/12/03 Javascript
详解js的事件处理函数和动态创建html标记方法
2016/12/16 Javascript
详解浏览器渲染页面过程
2017/02/09 Javascript
nodejs利用ajax实现网页无刷新上传图片实例代码
2017/06/06 NodeJs
浅谈react受控组件与非受控组件(小结)
2018/02/09 Javascript
详解Vue改变数组中对象的属性不重新渲染View的解决方案
2018/09/21 Javascript
微信小程序实现自动定位功能
2018/10/31 Javascript
微信小程序登录session的使用
2019/03/17 Javascript
node.js ws模块搭建websocket服务端的方法示例
2019/04/25 Javascript
JS使用cookie保存用户登录信息操作示例
2019/05/30 Javascript
js布局实现单选按钮控件
2020/01/17 Javascript
微信小程序仿淘宝热搜词在搜索框中轮播功能
2020/01/21 Javascript
轻松掌握python设计模式之策略模式
2016/11/18 Python
Django Sitemap 站点地图的实现方法
2019/04/29 Python
基于python实现百度翻译功能
2019/05/09 Python
Python产生一个数值范围内的不重复的随机数的实现方法
2019/08/21 Python
Python对Tornado请求与响应的数据处理
2020/02/12 Python
不同浏览器创建XMLHttpRequest方法有什么不同
2014/11/17 面试题
酒吧总经理岗位职责
2013/12/10 职场文书
初一英语教学反思
2014/01/11 职场文书
《只有一个地球》教学反思
2014/02/14 职场文书
节能环保标语
2014/06/12 职场文书
高职教师先进事迹材料
2014/08/24 职场文书
2015年物业公司保洁工作总结
2015/10/22 职场文书
高二化学教学反思
2016/02/22 职场文书
2019年第四季度财务部门工作计划
2019/11/02 职场文书
Python WSGI 规范简介
2021/04/11 Python