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中while循环语句用法简单实例
May 07 Python
Python中死锁的形成示例及死锁情况的防止
Jun 14 Python
Ubuntu下创建虚拟独立的Python环境全过程
Feb 10 Python
Python数据类型之Dict字典实例详解
May 07 Python
浅析python 中大括号中括号小括号的区分
Jul 29 Python
PyQtGraph在pyqt中的应用及安装过程
Aug 04 Python
PyQt Qt Designer工具的布局管理详解
Aug 07 Python
windows中安装Python3.8.0的实现方法
Nov 19 Python
Python操作MySQL数据库实例详解【安装、连接、增删改查等】
Jan 17 Python
python实现翻译word表格小程序
Feb 27 Python
用Python生成HTML表格的方法示例
Mar 06 Python
使用tkinter实现三子棋游戏
Feb 25 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
给海燕B411配件机起死回生配上件
2021/03/02 无线电
php实现的AES加密类定义与用法示例
2018/01/29 PHP
PHP写API输出的时用echo的原因详解
2019/04/28 PHP
php pdo连接数据库操作示例
2019/11/18 PHP
laravel框架使用FormRequest进行表单验证,验证异常返回JSON操作示例
2020/02/18 PHP
JS控制输入框内字符串长度
2014/05/21 Javascript
js获取checkbox复选框选中的选项实例
2014/08/24 Javascript
JavaScript按值删除数组元素的方法
2015/04/24 Javascript
详解JavaScript的策略模式编程
2015/06/24 Javascript
js基于面向对象实现网页TAB选项卡菜单效果代码
2015/09/09 Javascript
jQuery Validate插件实现表单强大的验证功能
2015/12/18 Javascript
Java遍历集合方法分析(实现原理、算法性能、适用场合)
2016/04/25 Javascript
使用JavaScript实现弹出层效果的简单实例
2016/05/31 Javascript
JS实现的自定义显示加载等待图片插件(loading.gif)
2016/06/17 Javascript
protractor的安装与基本使用教程
2017/07/07 Javascript
js实现省市级联效果分享
2017/08/10 Javascript
vue2.0 和 animate.css的结合使用
2017/12/12 Javascript
node.js利用socket.io实现多人在线匹配联机五子棋
2018/05/31 Javascript
jquery实现垂直手风琴菜单
2020/03/04 jQuery
javascript设计模式 ? 组合模式原理与应用实例分析
2020/04/14 Javascript
实例讲解Python中SocketServer模块处理网络请求的用法
2016/06/28 Python
python找出列表中大于某个阈值的数据段示例
2019/11/24 Python
Python Selenium截图功能实现代码
2020/04/26 Python
浅谈Tensorflow加载Vgg预训练模型的几个注意事项
2020/05/26 Python
什么是python类属性
2020/06/10 Python
编译 pycaffe时报错:fatal error: numpy/arrayobject.h没有那个文件或目录
2020/11/29 Python
python爬虫爬取淘宝商品比价(附淘宝反爬虫机制解决小办法)
2020/12/03 Python
HTML5中的postMessage API基本使用教程
2016/05/20 HTML / CSS
联想智利官方网站:Lenovo Chile
2020/06/03 全球购物
Linux文件系统类型
2012/02/15 面试题
Laravel的加密解密与哈希实例讲解
2021/03/24 PHP
计算机网络毕业生自荐信
2013/10/01 职场文书
我的老师教学反思
2014/05/01 职场文书
大一新生期末自我评价
2014/09/12 职场文书
SQL CASE 表达式的具体使用
2022/03/21 SQL Server
mysql数据库如何转移到oracle
2022/12/24 MySQL