Python UDP编程

前面我们讲了 TCP 编程,我们知道 TCP 可以建立可靠连接,并且通信双方都可以以流的形式发送数据。本文我们再来介绍另一个常用的协议--UDP。相对TCP,UDP则是面向无连接的协议。

UDP 协议

我们来看 UDP 的定义:

UDP 协议(User Datagram Protocol),中文名是用户数据报协议,是 OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。

从这个定义中,我们可以总结出 UDP 的几个特点以及其与 TCP 的区别:

  • UDP 是用户数据报协议,传输模式是数据报,而 TCP 是基于字节流的传输协议。

  • UDP 是无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。

  • UDP 是简单不可靠的协议,它不提供可靠性,只是把数据包发送出去,并不保证能够到达目的地。由于它不需要在客户端和服务端之间建立连接,也没有超时重发机制,所以传输速度很快。

从以上特点,我们可以看到 UDP 适合应用在每次传输数据量小、对数据完整性要求不高、对传输速度要求高的领域。这里面最典型的就是即时通信的场景,微信是一个很常见的例子。相信大家在使用微信的时候都遇到过先发的消息后收到,或者有些发送的消息对方没有收到的情况吧,这就是 UDP 协议典型的特点,不保证传输数据的完整性和顺序性。除此之外, UDP 还应用在在线视频、网络电话等场景。

UDP 传输过程

我们在讲 TCP 的时候,我们说 TCP 客户端和服务端必须先连接才可以传输数据:客户端先请求连接服务器,服务器接受连接请求,然后双方才可以通信。在 UDP 协议里,客户端只需要知道服务器的地址和端口号,就可以直接发送数据了。

我们来看下 UDP 传输的流程图:

图片

TCP服务器的建立可以归纳这几步:

  • 创建 socket(套接字)

  • 绑定 socket 的 IP 地址和端口号

  • 接收客户端数据

  • 关闭连接

TCP客户端的创建可总结为这几步:

  • 创建 socket(套接字)

  • 向服务器发送数据

  • 关闭连接

这里需要注意的是 UDP 客户端连接到服务器的 IP 和端口号必须是 UDP 服务器的 IP 和监听的端口号,服务器服务器只需要绑定 IP 和端口号,就可以时刻准备接收客户端发送的数据,此时服务器处于阻塞状态,直到接收到数据为止。

UDP 客户端

创建 socket,可以这样做:

# 导入socket库import socket# 创建一个sockets = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

创建 socket 时,第一个参数 socket.AF_INET 表示指定使用 IPv4 协议,如果要使用 IPv6 协议,就指定为 socket.AF_INET6。SOCK_DGRAM 指定基于 UDP 的数据报式 Socket 通信。

创建了 socket 之后,我们就可以向目标地址发送数据报了:​​​​​​​

# 发送数据s.sendto(b'Hello Server', ('127.0.0.1', 6000))

第一个参数是需要发送的数据报内容,第二个参数是 IP 地址和端口号的二元组。

如果是接收数据的话,我们可以这样写:​​​​​​​

# 接收数据data, addr = s.recv(1024)# 解码接收到的数据data = data.decode('utf-8')

接收信息的时候,第一个 data 表示接收到的数据, addr 是对方的 IP 地址和端口号的二元组。

想要关闭 socket,直接调用 close() 方法即可:​​​​​​​

# 关闭 socketsocket.close()

UDP 服务器

相比于客户端,服务器端只是多了一个步骤,在创建 socket 之后,需要绑定一个 IP 地址和端口号,以便接收客户端随时可能发送过来的数据。绑定的方法为:​​​​​​​

# 绑定 IP 和端口s.bind(('127.0.0.1', 6000))

UDP 简单实例

我们通过一个简单的实例来体会下 UDP 的客户端和服务器的通信流程。

服务器代码为:​​​​​​​

import socket# 创建 socketsk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)# 绑定 IP 和端口号sk.bind(('127.0.0.1', 6000))while True:    # 接收数据报    msg, addr = sk.recvfrom(1024)    # 打印    print('来自[%s:%s]的消息: %s' % (addr[0], addr[1], msg.decode('utf-8')))    # 等待输入    inp = input('>>>')    # 发送数据报    sk.sendto(inp.encode('utf-8'), addr)# 关闭 socketsk.close()

这里,我们先创建 socket,然后绑定本机的6000端口,然后等待接收客户端发送的数据报,接收到数据后将数据内容打印在控制台。然后可以在控制台输入回复内容,发送给客户端。

客户端代码:​​​​​​​

import socket# 创建 socketsk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)addr = ('127.0.0.1', 6000)while True:    # 等待输入    msg = input('>>>')    # 发送数据报    sk.sendto(msg.encode('utf-8'), addr)    # 接收数据报    msg_recv, addr = sk.recvfrom(1024)    # 打印    print(msg_recv.decode('utf-8'))# 关闭 socketsk.close()

在客户端代码中,我们就只是创建 socket,然后在控制台输入需要向服务器发送的内容,通过 sentto() 方法发送给服务器,然后接收服务器返回的内容,将接收的内容打印到控制台。

分别运行客户端和服务器代码,然后我们在客户端的控制台输入 “hello server”,我们可以看到服务器的控制台打印了客户端发送的内容,然后我们在服务器控制台输入 “hello client”,同样在客户端控制台可以看你到内容。

下面是客户端的控制台内容:​​​​​​​

>>>hello serverhello client>>>

下面是服务器的控制台内容:​​​​​​​

来自[127.0.0.1:61207]的消息: hello server>>>hello client

这个实例其实就是一个简单的聊天模型,客户端和服务器就像两个人一样可以发送和接收对方的信息。

那么多人群聊怎么实现呢?简单来说,我们需要设置一台中心服务器,我们每个人发送的内容都先发送到中心服务器,然后中心服务器再转发到每个群聊的人。

总结

本文为大家介绍了 UDP 编程的基本原理以及通过 Python 实现一个最简单的聊天程序来模拟 UDP 通信的过程。通过本文的学习,我们需要对 UDP 协议有基本的认识,以及对 UDP 的通信过程比较熟悉。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/114325.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot整合jquery实现前后端数据交互

一 实施逻辑 1.1 前端 <!doctype html> <html lang"en"><head><meta charset"UTF-8"><meta name"Generator" content"EditPlus"><meta name"Author" content""><meta n…

FFDNet-pytorch版本代码训练教程

一、FFDNet-pytorch版本代码下载 (1)FFDNet-pytorch下载 https://download.csdn.net/download/qq_41104871/88233742 (2)FFDNet-pytorch版本代码运行环境配置 https://blog.csdn.net/qq_41104871/article/details/132497008 二、FFDNet-pytorch版本代码训练教程 (1)按…

并发编程的故事——共享模式之无锁

共享模式之无锁 文章目录 共享模式之无锁一、提出问题二、CAS和volatile三、原子整数四、原子引用五、原子数组六、原子更新器七、原子累加器八、unsafe 一、提出问题 关于对共享变量修改的多线程问题其实就是指令交错问题导致取值的时机相同&#xff0c;最后修改之后以最后一…

Rabbitmq安装

1、安装说明 安装RabbitMq时需注意&#xff0c;需要先安装Erlang。因为RabbitMq依赖于Erlang&#xff0c;且两者之间的版本是有对应关系的&#xff0c;详细可查看&#xff1a;版本对照表 此外&#xff0c;需要注意的是本教程中采用的安装方式是使用源码安装。非rpm或一键安装方…

精读《算法题 - 地下城游戏》

今天我们看一道 leetcode hard 难度题目&#xff1a;地下城游戏。 恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里&#xff0c;他必须穿过地下城并通过对抗恶魔来拯救公主。 骑士…

【若依框架RuoYi-Vue-Plus 图片回显不显示问题,OSS文件上传或者本地上传】

一、问题 1.设计表 product&#xff08;商品表&#xff09; 有 id &#xff08;id&#xff09; name&#xff08;商品名&#xff09;icon&#xff08;图标&#xff09; 2.使用若依代码生成功能&#xff0c;导入product表&#xff0c;代码生成。 3.将生成的代码导入到项目中得到…

线性代数的学习和整理16:什么是各种空间(类型),向量空间,距离(类型)?

目录 1 空间相关的群&#xff0c;环&#xff0c;域&#xff0c;集合&#xff0c;空间的预备知识 1.1&#xff1a;群&#xff0c;环&#xff0c;域&#xff0c;集合&#xff0c;空间的定义&#xff08;表示不懂&#xff0c;只是做个标记&#xff09; 2 空间 2.1 各种空间概念…

客路旅行(KLOOK)面试(部分)(未完全解析)

一面 用过Chatgpt的哪个版本&#xff0c;了解Chatgpt版本之间的差异吗 什么是优雅部署&#xff1f;newBing: 服务启动时&#xff0c;检查依赖的组件或容器是否就绪&#xff0c;如果不就绪&#xff0c;等待或重试&#xff0c;直到就绪后再注册到服务中心&#xff0c;对外提供服…

Spring三级缓存解决循环依赖

Spring三级缓存解决循环依赖 一 Spring bean对象的生命周期 二 三级缓存解决循环依赖 实现原理解析 spring利用singletonObjects, earlySingletonObjects, singletonFactories三级缓存去解决的&#xff0c;所说的缓存其实也就是三个Map 先实例化的bean会通过ObjectFactory半…

Ubuntu学习---跟着绍发学linux课程记录(第一部分)

文章目录 1、启动、关闭、挂起、恢复&#xff08;电源&#xff09;2、更多虚拟机操作2.1 电源设置2.2 硬件参数设置2.3 状态栏2.4 全屏显示 3、快照与系统恢复4、桌面环境5、文件系统6、用户目录7、创建目录和文件8、命令行&#xff1a;文件列表ls 9、命令行&#xff1a;切换目…

skywalking agent监控java服务

一、前言 skywalking agent可以监控的服务类型有多种&#xff0c;python、go、java、nodejs服务等都可以监控&#xff0c;现在通过java服务来演示skywalking agent的使用&#xff0c;并且是使用容器的方式实现 二、部署skywalking agent监控 需要注意&#xff0c;skywalking…

JVM类加载器

一、类与类加载器 类加载器虽然只用于实现类的加载动作&#xff0c;但它在Java程序中起到的作用却远超类加载阶段。对于 任意一个类&#xff0c;都必须由加载它的类加载器和这个类本身一起共同确立其在Java虚拟机中的唯一性&#xff0c;每一个类加载器&#xff0c;都拥有一个独…

每日一题:leetcode 1448 统计二叉树中好节点的数目

给你一棵根为 root 的二叉树&#xff0c;请你返回二叉树中好节点的数目。 「好节点」X 定义为&#xff1a;从根到该节点 X 所经过的节点中&#xff0c;没有任何节点的值大于 X 的值。 示例 1&#xff1a; 输入&#xff1a;root [3,1,4,3,null,1,5] 输出&#xff1a;4 解释&a…

群晖NAS:DSM7.1激活Advanced Media Extensions【自留记录】

群晖NAS&#xff1a;DSM7.1激活Advanced Media Extensions【自留记录】 本文仅半白群晖可用&#xff0c;不需要安装其他套件或者ssh修改什么 使用DS Video 网页播放视频时候&#xff0c;提示&#xff1a;【不支持当前所选音轨的文件格式&#xff0c; 因此无法播放视频。请尝试…

Vue-Router 一篇搞定 Vue3

前言 在 Web 前端开发中&#xff0c;路由是非常重要的一环&#xff0c;但是路由到底是什么呢&#xff1f; 从路由的用途上讲 路由是指随着浏览器地址栏的变化&#xff0c;展示给用户不同的页面。 从路由的实现原理上讲 路由是URL到函数的映射。它将 URL 和应用程序的不同部分…

Leetcode415 字符串相加

思路&#xff1a; 从末尾开始相加&#xff0c;进位可以最后统一处理&#xff0c;因为再怎么进也是最多只进一位 class Solution:def addStrings(self, num1: str, num2: str) -> str:# 确保1里是更长的字符串if len(num1) < len(num2):num1_list list(num2)num2_list …

解决Spring Data JPA中的NullPointerException问题

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

简单了解OSI网络模型

目录 一、协议是什么&#xff1f; 二、OSI七层模型 三、TCP/IP五层模型 一、协议是什么&#xff1f; 协议顾名思义就是通过大家伙一起协商讨论达成的统一规则和标准。网络协议就是规定用户数据信息如何在网络上传播以及实现某种网络技术所要遵循的统一标准和规则。 二、OSI…

电脑使用快捷键的各种方法

电脑使用快捷键可以帮助我们提高日常操作效率&#xff0c;例如&#xff1a; CTRLC&#xff1a;复制选中内容。 CTRLV&#xff1a;粘贴复制的内容。 CTRLX&#xff1a;剪切选中内容。 CTRLA&#xff1a;全选当前页面内容。 SHIFTDELETE&#xff1a;永久删除选中内容。 CTRL…

华为OD机试 - 租车骑绿道 - 双指针(Java 2023 B卷 100分)

目录 一、题目描述二、输入描述三、输出描述四、解题思路1、输入2、输出3、说明4、双指针算法 五、Java算法源码六、效果展示 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 一、题目描述 部门组织绿岛骑行团建活动&#xff0c;租用公共双人自行车骑行&#xff0c;…