一个简单的UDP服务端与客户端

服务端: 

 from socket import *
#创建套接字
udp_server = socket(AF_INET,SOCK_DGRAM) msg_server = ("",8877)
#绑定ip地址和端口
udp_server.bind(msg_server) while True:
#接受消息,注意此处用的是 recvfrom()
msg_client = udp_server.recvfrom(1024) print("新客户端已连接--->>>") if len(msg_client) != 0:
#msg_client中有两个值,第一个表示收到的消息的内容,第二个表示客户端的IP地址和端口的信息
print("%s:%s" % (msg_client[1], msg_client[0].decode("utf-8")))
else:
break udp_server.close()

客户端:

from socket import *

sock = socket(AF_INET,SOCK_DGRAM)

addr_msg = ("192.168.1.104",8877)
#连接服务端
sock.connect(addr_msg) while True:
msg_send = input("请输入要发送的信息:")
if msg_send =='q':
break
#注意此处用的是sendto() 其中第一个参数表示要发送的消息的内容,第二个参数表示服务端的IP地址和端口的元组
sock.sendto(msg_send.encode("utf-8"),addr_msg) sock.close()

基于UDP的tftp文件传输

客户端:

 from socket import *
import struct
import os def main():
file_name = input("请输入要下载的文件名:")
#建立一个UDP的套接字
udpsocket = socket(AF_INET,SOCK_DGRAM)
#创建一个tftp的下载请求 H表示第一个参数占用两个字节,d表示对应的参数为bite类型
# %ds 表示文件名占用的字符个数,如后面的octet占用了5个字符,所以写成5s
# octet是tftp传输的一种模式,它决定了传输数据的格式,还有其他的几种tftp传输的模式
#构造包使用的是struck中的pack ,其中的 H 表示使参数占用两个字节
request_header = struct.pack("!H%dsb5sb"%len(file_name),1,file_name.encode('utf-8'),0,b"octet",0)
server_msg = ("192.168.0.100",69)
#发送一个下载文件的请求
udpsocket.sendto(request_header,server_msg) # 这里必须以wb的格式打开文件,否则文件不能正常显示
f = open(file_name,"wb") # num表示的是数据块的编号,这里使得其初始值为0
num = 0
#此处建立一个标记,以确认传输过程中没发生错误
mask = True while True:
# 接收服务端发来的数据包
response_data = udpsocket.recvfrom(1024)
recv_data, server_info = response_data # 此处用struct中的unpack来解包 H 表示数据占用两个字节长度
# 这里的前两个字节中存储的是操作码
operation_num = struct.unpack("!H",recv_data[:2])
# 这里的第三个和第四个字节中存储的是数据块的编号
package_num = struct.unpack("!H",recv_data[2:4])
print(package_num[0]) # 操作码为3时表示接收到的信息是服务端收到响应而发给客户端的数据包
if operation_num[0] == 3:
#这一次收到的值应该是在上一次收到的值的基础上加上一后的结果
num =num + 1
#此处表示一旦num的值超过了它2个字节所表示的值的范围,则让它从0开始再来重复一遍(主要是因为操作码只能占2个字节)
if num == 65535:
num = 0
# 进行块编号的确认
if num == package_num[0]: #此处取下标是因为此时的package_num表示的是一个元组,而块编号是元组中的第一个数据
# 将收到的具体数据写入到文件中
f.write(recv_data[4:])
#块编号的确认每次都要在之前的值上加1
num = package_num[0]
#构造一个响应包 操作码为4 发送的数据就是加上1后的块编号
ack_data = struct.pack("!HH",4,package_num[0])
#发送响应包
udpsocket.sendto(ack_data, server_info) elif operation_num[0] == 5:
print("Error!")
#若发生错误信息,则将标记的值改成False , 以便后续操作删除这个文件
mask = False
f.close() # 一个数据包的最大长度为 4+512 = 516 位,如果数据包小于这个数值,则表明这已经是最后一次的数据传输了
if len(recv_data) < 516:
print("Finish!")
break
# mask标记的值为True则表示文件传输的过程中没有发生错误,就将本地接收到的文件关闭保存
if mask == True:
f.close() else:
# mask标记的值为False则表示文件传输的过程中出现了错误信息,则将已经接收到的文件删除
os.remove(file_name) if __name__ == "__main__":
main()

至于服务端可以用 tftpd32 这个软件来模拟实现

关于TFTP协议

TFTP协议是一种基于UDP的小型文件传输协议,它不具备FTP的许多功能

TFTP的端口号为69

一个数据包在接受的过程中最大长度为512+2+2=516字节,所以当它的长度小于516字节时便可以判断出这是最后一次的数据传输

上面构造数据包时使用的H的意思是,让它所代表的参数占用两个字节的长度,从而使数据包符合TFTP协议的要求

Tftp文件传输服务器(基于UDP协议)的更多相关文章

  1. vsftpd-基于ftp协议的文件传输服务器软件

    第一部分:在Linux上部署vsftpd服务 1. vsftpd简介 1.1 vsftpd是什么? ftp(File Transfer Protocol)文件传输协议.(实现不同操作系统之间文件的传输 ...

  2. c++下基于windows socket的服务器客户端程序(基于UDP协议)

    前天写了一个基于tcp协议的服务器客户端程序,今天写了一个基于UDP协议的,由于在上一篇使用TCP协议的服务器中注释已经较为详细,且许多api的调用是相同的,故不再另外注释. 使用UDP协议需要注意几 ...

  3. Python中的端口协议之基于UDP协议的通信传输

    UDP协议: 1.python中基于udp协议的客户端与服务端通信简单过程实现 2.udp协议的一些特点(与tcp协议的比较)        3.利用socketserver模块实现udp传输协议的并 ...

  4. 网络编程——基于TCP协议的Socket编程,基于UDP协议的Socket编程

    Socket编程 目前较为流行的网络编程模型是客户机/服务器通信模式 客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求.如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服 ...

  5. 基于UDP协议的控制台聊天程序(c++版)

    本博客由Rcchio原创,转载请告知作者 ------------------------------------------------------------------------------- ...

  6. python 全栈开发,Day34(基于UDP协议的socket)

    昨日内容回顾 网络的基础概念arp协议 :通过ip地址找到mac地址五层模型 : 应用层 传输层 网络层 数据链路层 物理层tcp协议 : 可靠的 面向连接 全双工 三次握手 四次挥手udp协议 : ...

  7. (1)基于tcp协议的编程模型 (2)tcp协议和udp协议的比较 (3)基于udp协议的编程模型 (4)反射机制

    1.基于tcp协议的编程模型(重中之重)1.1 编程模型服务器: (1)创建ServerSocket类型的对象,并提供端口号: (2)等待客户端的连接请求,调用accept()方法: (3)使用输入输 ...

  8. Linux内核--网络栈实现分析(五)--传输层之UDP协议(上)

    本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明出处http://blog.csdn.net/yming0221/article/details/7532512 更多请看专栏, ...

  9. 网络编程应用:基于UDP协议【实现文件下载】--练习

    要求: 基于UDP协议实现文件下载 发送方–请求–接收方发送文件–发送方接收文件 代码: 发送方: package Homework1; import java.io.File; import jav ...

随机推荐

  1. VMware 安装 CentOS 7

    下载并安装 VMware 访问 VMware 官方网站下载 VMware 安装包程序.博主使用的是 12.5.5 版本,下载完之后点击安装包程序进入 VMware 的安装向导,然后点击"下一 ...

  2. .Net基础之5——复杂数据类型

    (1)复习 1.变量 int  double   string   char   bool    decimal 变量的使用规则:先声明再赋值最后使用 2.Camo      Pascal 3.运算符 ...

  3. Flutter “孔雀开屏”的动画效果

    老孟导读:今天分享一个类似"孔雀开屏"的动画效果,打开新的页面时,新的页面从屏幕右上角以圆形逐渐打开到全屏. 先来看下具体的效果 不知道这种效果大家叫什么名字?如果有更合适的名字可 ...

  4. java——定时任务

    java定时任务直接看代码 public void timeTask(){ Timer timer = new Timer(); timer.schedule(new TimerTask() { pu ...

  5. Spring bean工厂配置头文件

    命名 beans.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...

  6. 谈谈对ThreadLocal类的理解

    源码中对于ThreadLocal类的解释是: /** * This class provides thread-local variables. These variables differ from ...

  7. 整理总结数据库常用sql语句,建议收藏,忘记了可以来看一下

    第一节课:sql语言介绍(参照PPT)及基本查询sql学习 1.数据库表的介绍 emp表:员工表 dept表:部门表 salgrady:薪资水平表 Balance: 2.基本的查询语句: 知识点: s ...

  8. 【Ubuntu】Ubuntu系统启动过程中,输入用户名与密码后登录一直卡在紫色界面问题(未解决,最后通过重装系统)

    0. 前言 由于本电脑为公用电脑,可能由于其他人点了图像界面中推荐的内核更新,导致原来安装的NVIDIA显卡驱动 430 与升级后的 5.0 内核不兼容,从而导致输入用户名后登录一直卡在紫色界面.在排 ...

  9. win10下安装scrapy出现错误的处理

    一.背景: 在win10的dos窗口下使用命令pip install scrapy安装scrapy时,出现“ error: Microsoft Visual C++ 14.0 is required. ...

  10. 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(一)

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...