当前位置: 首页 > news >正文

python之UDP网络应用程序开发

文章目录

  • 版权声明
  • UDP网络应用程序开发
    • UDP初识
    • UDP知识要点
    • socket类的使用
    • UDP发送数据开发流程分析
    • UDP服务客户端通信栗子
    • UDP广播发送

版权声明

  • 本博客的内容基于我个人学习黑马程序员课程的学习笔记整理而成。我特此声明,所有版权属于黑马程序员或相关权利人所有。本博客的目的仅为个人学习和交流之用,并非商业用途。
  • 我在整理学习笔记的过程中尽力确保准确性,但无法保证内容的完整性和时效性。本博客的内容可能会随着时间的推移而过时或需要更新。
  • 若您是黑马程序员或相关权利人,如有任何侵犯版权的地方,请您及时联系我,我将立即予以删除或进行必要的修改。
  • 对于其他读者,请在阅读本博客内容时保持遵守相关法律法规和道德准则,谨慎参考,并自行承担因此产生的风险和责任。本博客中的部分观点和意见仅代表我个人,不代表黑马程序员的立场。

UDP网络应用程序开发

UDP初识

  • UDP(User Datagram Protocol)是一种无连接的传输层协议,它不保证数据传输的可靠性和有序性,但具有传输速度快的优点
  • UDP协议可以用于音频、视频、游戏等实时应用场景,因为这些应用对数据传输的实时性要求较高,而对数据传输的可靠性和有序性要求较低。
  • UDP通信的优点是速度快,适用于实时应用场景,但缺点是不可靠,容易丢失数据,因此在需要保证数据传输可靠性的场景下不适用。
    UDP通信的基本流程如下:
  1. 发送端将要发送的数据打包成UDP数据包,包括目标IP地址、目标端口号、数据长度和数据内容等信息。

  2. 发送端将UDP数据包发送给目标主机。

  3. 接收端接收到UDP数据包后,将数据包中的信息解析出来,包括发送端IP地址、发送端端口号、数据长度和数据内容等信息。

  4. 接收端根据发送端的IP地址和端口号,将数据传输到相应的应用程序中进行处理。


UDP知识要点

  1. UDP网络通信本质不区分客户端和服务端,在实际应用中,通常会将发送数据的一方称为客户端,将接收数据的一方称为服务端。
    • 在实际应用中,客户端通常是发送请求的一方,服务端通常是提供服务的一方。例如,在客户端与服务端之间进行网络游戏通信时,客户端会向服务端发送游戏请求,服务端会接收请求并处理,然后再将处理结果发送回客户端。在这种情况下,客户端和服务端的角色是明确的。
  2. UDP协议可以直接通过对方IP地址和端口号发送数据,而不需要像TCP协议那样需要先建立连接。
    • 在UDP协议中,发送数据时需要指定目标主机的IP地址和端口号,数据直接发送到目标主机。接收数据时,可以通过绑定本地IP地址和端口号来指定接收数据的地址和端口号,然后等待数据的到来。当有数据到达时,就可以直接从数据包中获取发送方的IP地址和端口号,从而实现直接通信。
  3. 在UDP协议中,可以指定一个固定的端口用于发送和接收数据,也可以让操作系统自动选择一个空闲端口。
    • 在发送UDP数据时,可以指定源端口和目标端口。如果指定了源端口,那么每次发送数据时就会使用该端口。如果未指定源端口,操作系统会自动选择一个空闲端口,然后发送数据。在接收UDP数据时,可以指定一个固定的端口来接收数据。如果未指定端口,操作系统会自动选择一个空闲端口来接收数据。

socket类的使用

  • 参看python之TCP的网络应用程序开发的socket类的使用部分的内容
  • 栗子
  1. 创建UDP套接字对象:
    import socket# 创建UDP套接字对象
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
  2. 绑定本地IP地址和端口号:
    # 绑定本地IP地址和端口号
    local_addr = ('127.0.0.1', 8888)
    udp_socket.bind(local_addr)
    
  3. 发送UDP数据:
    # 发送UDP数据
    dest_addr = ('127.0.0.1', 9999)
    send_data = 'Hello, UDP!'
    udp_socket.sendto(send_data.encode('utf-8'), dest_addr)
    
  4. 接收UDP数据:
    # 接收UDP数据
    recv_data, remote_addr = udp_socket.recvfrom(1024)
    print('Received from %s:%s' % remote_addr)
    print(recv_data.decode('utf-8'))
    
  5. 关闭UDP套接字对象:
    # 关闭UDP套接字对象
    udp_socket.close()
    

UDP发送数据开发流程分析

  • 服务端:
    1. 创建UDP套接字对象
    2. 绑定本地IP地址和端口号
    3. 接收UDP数据
    4. 发送UDP数据
    5. 关闭UDP套接字对象
  • 客户端:
    1. 创建UDP套接字对象
    2. 发送UDP数据
    3. 接收UDP数据
    4. 关闭UDP套接字对象

UDP服务客户端通信栗子

  • UDP服务端
import socketif __name__ == '__main__':# 创建UDP套接字对象udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)# 设置为非阻塞模式udp_socket.setblocking(False)# 绑定本地IP地址和端口号local_addr = ('127.0.0.1', 8888)udp_socket.bind(local_addr)while True:try:# 接收UDP数据recv_data, remote_addr = udp_socket.recvfrom(1024)print('Received from %s:%s' % remote_addr)print(recv_data.decode('utf-8'))# 发送UDP数据send_data = 'Hello, UDP客户端!'udp_socket.sendto(send_data.encode('utf-8'), remote_addr)except BlockingIOError:pass# 发送UDP数据send_data = 'Hello, UDP客户端!'udp_socket.sendto(send_data.encode('utf-8'), remote_addr)# 关闭UDP套接字对象udp_socket.close()
  • UDP客户端
import socket
if __name__ == '__main__':# 创建UDP套接字对象udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)# 设置为非阻塞模式udp_socket.setblocking(False)# 发送UDP数据dest_addr = ('127.0.0.1', 8888)send_data = 'Hello, UDP服务端!'udp_socket.sendto(send_data.encode('utf-8'), dest_addr)# 接收UDP数据while True:try:recv_data, remote_addr = udp_socket.recvfrom(1024)print('Received from %s:%s' % remote_addr)print(recv_data.decode('utf-8'))breakexcept BlockingIOError:pass# 关闭UDP套接字对象udp_socket.close()

UDP广播发送

  • 广播地址(Broadcast Address)是专门用于同时向网络中所有工作站进行发送的一个地址

  • 广播地址是一个特殊的IP地址,用于向一个网络中的所有设备发送数据。在IPv4中,广播地址是由主机地址全为1和网络地址组成的地址。例如,如果你的网络地址是192.168.1.0,那么广播地址就是192.168.1.255。

import socketif __name__ == '__main__':# 创建UDP套接字对象 将UDP套接字对象设置为广播模式udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)# 设置广播选项 socket.SO_BROADCAST广播udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)# 广播地址dest_addr = ('192.168.1.255', 8888)# 发送UDP数据send_data = 'Hello, UDP broadcast!'udp_socket.sendto(send_data.encode('utf-8'), dest_addr)# 关闭UDP套接字对象udp_socket.close()

相关文章:

  • selinux-policy-default(2:2.20231119-2)软件包内容详细介绍(2)
  • ⑧【HyperLoglog】Redis数据类型:HyperLoglog [使用手册]
  • 搜索引擎---项目测试
  • 如何取消thunar为默认文件管理器
  • MySQL索引 Error1071
  • 基于单片机的温湿度检测系统设计
  • 遥遥领先!TinyEngine 低代码引擎更新升级!AI 已成功部署!
  • JMeter 设置请求头信息的详细步骤
  • ⑦【Redis GEO 】Redis常用数据类型:GEO [使用手册]
  • centos7卸载mongodb数据重新安装时无法安装的问题
  • 3.1 CPU内部结构与时钟与指令
  • Vite CSS Module 优雅的处理样式隔离
  • R数据分析:集成学习方法之随机生存森林的原理和做法,实例解析
  • CentOS 7实现类似于Kali Linux中的自动补全功能
  • css实现图片绕中心旋转,鼠标悬浮按钮炫酷展示
  • 5、React组件事件详解
  • JavaScript新鲜事·第5期
  • Java读取Properties文件的六种方法
  • node入门
  • React-Native - 收藏集 - 掘金
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 聊聊hikari连接池的leakDetectionThreshold
  • 思维导图—你不知道的JavaScript中卷
  • 学习ES6 变量的解构赋值
  • 学习HTTP相关知识笔记
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • ​io --- 处理流的核心工具​
  • ​力扣解法汇总946-验证栈序列
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • (C语言)输入一个序列,判断是否为奇偶交叉数
  • (Python) SOAP Web Service (HTTP POST)
  • (一)基于IDEA的JAVA基础1
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .Net 4.0并行库实用性演练
  • .Net Winform开发笔记(一)
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .NET 的静态构造函数是否线程安全?答案是肯定的!
  • .net 流——流的类型体系简单介绍
  • .NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)
  • .NET应用架构设计:原则、模式与实践 目录预览
  • .Net转Java自学之路—基础巩固篇十三(集合)
  • /usr/bin/python: can't decompress data; zlib not available 的异常处理
  • @DataRedisTest测试redis从未如此丝滑
  • @serverendpoint注解_SpringBoot 使用WebSocket打造在线聊天室(基于注解)
  • [20150629]简单的加密连接.txt
  • [AI]文心一言爆火的同时,ChatGPT带来了这么多的开源项目你了解吗
  • [Android]使用Android打包Unity工程
  • [C#]winform部署yolov5-onnx模型
  • [C++]打开新世界的大门之C++入门
  • [CTO札记]如何测试用户接受度?
  • [C语言]——内存函数
  • [Flutter] extends、implements、mixin和 abstract、extension的使用介绍说明
  • [HTML]Web前端开发技术30(HTML5、CSS3、JavaScript )JavaScript基础——喵喵画网页