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单例模式与metaclass
Jan 15 Python
Python实现Youku视频批量下载功能
Mar 14 Python
Python 绘图库 Matplotlib 入门教程
Apr 19 Python
python中subprocess批量执行linux命令
Apr 27 Python
Django web框架使用url path name详解
Apr 29 Python
python实现最小二乘法线性拟合
Jul 19 Python
Python2与Python3的区别详解
Feb 09 Python
Python使用GitPython操作Git版本库的方法
Feb 29 Python
使用python采集Excel表中某一格数据
May 14 Python
Python 删除List元素的三种方法remove、pop、del
Nov 16 Python
Pandas搭配lambda组合使用详解
Jan 22 Python
基于PyQt5制作一个群发邮件工具
Apr 08 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基础知识:类与对象(2) 自动加载对象
2006/12/13 PHP
PHP STRING 陷阱原理说明
2010/07/24 PHP
屏蔽PHP默认设置中的Notice警告的方法
2016/05/20 PHP
PHP策略模式定义与用法示例
2017/07/27 PHP
详解php curl带有csrf-token验证模拟提交方法
2018/04/18 PHP
PHP排序算法之归并排序(Merging Sort)实例详解
2018/04/21 PHP
jQuery学习2 选择器的使用说明
2010/02/07 Javascript
jQuery老黄历完整实现方法
2015/01/16 Javascript
JQuery调用绑定click事件的3种写法
2015/03/28 Javascript
移动端H5开发 Turn.js实现很棒的翻书效果
2016/06/20 Javascript
微信小程序 animation API详解及实例代码
2016/10/08 Javascript
layer弹出层框架alert与msg详解
2017/03/14 Javascript
Django使用多数据库的方法
2017/09/06 Javascript
详解webpack多页面配置记录
2018/01/22 Javascript
Vue2.5 结合 Element UI 之 Table 和 Pagination 组件实现分页功能
2018/01/26 Javascript
angular4 JavaScript内存溢出问题
2018/03/06 Javascript
使用JavaScript中的lodash编写双色球效果
2018/06/24 Javascript
vue-rx的初步使用教程
2018/09/21 Javascript
js array数组对象操作方法汇总
2019/03/18 Javascript
浅析webpack-bundle-analyzer在vue-cli3中的使用
2019/10/23 Javascript
js实现鼠标滑动到某个div禁止滚动
2020/09/17 Javascript
Linux下使用python自动修改本机网关代码分享
2015/05/21 Python
python中set常用操作汇总
2016/06/30 Python
Django 导出 Excel 代码的实例详解
2017/08/11 Python
python发送邮件脚本
2018/05/22 Python
python 解决flask 图片在线浏览或者直接下载的问题
2020/01/09 Python
PyCharm取消波浪线、下划线和中划线的实现
2020/03/03 Python
你需要学会的8个Python列表技巧
2020/06/24 Python
检测浏览器对HTML5和CSS3支持度的方法
2015/06/25 HTML / CSS
美国购买新书和二手书网站:Better World Books
2018/10/31 全球购物
Bata印度官网:源自欧洲舒适鞋履品牌
2020/01/30 全球购物
金属材料工程个人求职的自我评价
2013/12/04 职场文书
国家助学金感谢信
2015/01/21 职场文书
餐饮服务员岗位职责
2015/02/09 职场文书
MySQL库表名大小写的选择
2021/06/05 MySQL
口袋妖怪冰系十大最强精灵,几何雪花排第七,第六类似北极熊
2022/03/18 日漫