news 2026/3/3 17:37:11

网络编程UDP

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
网络编程UDP

操作系统会提供一组API(socket.api)接口进行网络通讯

传输层的两个核心协议

TCP:有连接,可靠传输,面向字节流,全双工

UDP:无连接,不可靠传输,面向数据报,全双工

有连接vs无连接

这个连接不是物流意义上的连接,是抽象,虚拟概念的连接。

在TCP中,A和B通信,A和B先建立连接,然后A会保存B的信息,B也会保存A的信息,让他们知道彼此之间是和谁在进行通信。

UDP中,则不会保存这样的信息,不管对方是谁,这个就叫做无连接

举例子

结婚,两个人结婚就之后,会有结婚证,一式两份,上面就会写着对方的信息,比如A是B的老公,B是A的老婆。这个就叫做有连接

可靠传输vs不可靠传输

在网络传输中,丢包是很常见的事情,受到外界的各种干扰就会导致丢包,当我们发出一个数据包的时候,并不指望他能够100%到达对方

可靠传输:并不能100%的送达,只是说尽可能的送达

不可靠传输:管你那么多,我送了,到不到就不关我事了

可靠传输虽然送达的完整度高,但是要付出效率低的代价,不可靠传输虽然送达完整度低,但是效率高。

面向字节流vs面向数据报

面向字节流:以字节为基本单位读写数据,支持任意长度会出现粘包的问题(读一半)

面向数据报:以一个数据报为基本单位读写数据,每次读取必须1个完整的数据报,不支持任意长度但是不会出现粘包

全双工vs半双工

全双工:一个通信链路中,支持双向通信,能读也能写

半双工:一个通信链路中,支持单向通信,只能写或者只能读

Socket.api进行网络编程

在计算机中,文件广义上来说,是操作系统操作管理的一种形式,同时,硬件也可以抽象成一个文件,进行统一的管理。

网卡==socket文件

操作过程就和操作普通的文件差不多,打开,读写,关闭,之所以不直接操作网卡,是因为不好操作,所以转化成文件,相当于遥控器

DategramSocket

表示的是通过操作系统调用socket.api来操作网卡

构造方法:相当于打开文件

第一个构造方法是随机绑定一个端口号

第二个是指定端口号

一个是接收,一个是发送,注意传入的是一个完整的数据报,因为你接收和发送的肯定是一个完整的数据报

DatagramPacket

表示的是一个完整的UDP数据报

UDP的数据包的载荷数据,可以通过构造方法来指定传入和传出

使用UdpEchoClient/Server模拟(回显服务器)

UdpEchoServer

思路

首先声明一个变量,类型是datagramsocket,然后在构造方法中传入一个端口号,同时初始化之前的变量,这个变量是datagramsocket类型的,这个类就相当于一个代理人,因为我们无法直接调用网卡,这个类就相当于一个代理人向操作系统申请一个窗口和网卡交流,,之后在start方法中要写入一个死循环,因为我们要让服务器进行不间断的工作,服务器的处理请求的过程一般分为三步,第一步,创建一个UDP数据包,读取请求,最好使用一个数组类型这样读取的快一些,然后使用socket.receive去读取,注意这个是一个阻塞的方法,会等待客户端输入,假如客户端输入了,因为网络传输的只能说二进制,所以下一步就是需要把这些二进制转成string类型,第二步就是响应请求,这里我用的是回显式,所以暂时先不管,第三步就是返回数据给客户端,我们要把之前转成字符串的转成二进制,这样才能在网络上传播,传播的时候要注意指定ip和端口号,最后返回即可。

具体代码实现:

这段代码中,首先是声明一个datagramsocket类型的变量,然后在构造方法中,我会传入一个端口号,因为我们在java中是无法直接操作网卡的,所以要借助datagramsocket这个类,可以理解为代理人,去和操作系统申请,让我们可以和网卡进行沟通,进而可以进行读写操作。

这里更是核心中的核心,首先,因为服务器需要不间断的进行工作,所以在这个start方法中,我们需要加入一个死循环来确保他能够24小时不间断工作(黑奴)。

服务器处理请求一般是分为三步

第一步,读取并解析请求

首先,我们需要提前准备好一个空的请求包,这个是为了之后在客户端输入的时候,我们能够读取到信息,然后使用socket.receive去读取这个数据包,接着需要把这些去读到的数据转化成字符串,方便我们能看懂

第二步,根据请求,计算响应(核心)

由于我这里演示的是回显式所以就比较简单

第三步,返回响应值

因为之前我们把他拆成字符串了,所以这个时候我们需要把他变回去成为二进制的数据,然后把他装到一个数据包里去,这个时候要注意给出发送的地址和端口号,最后发送即可。

可能你会有一个疑问,之前不是说UDP是无连接的吗,这个指的是长久的连接,一次的连接他是可以记住的,过了就忘了,所以这个时候可以获取到源IP和端口。

可能你还有一个疑问,既然说网卡可以抽象成文件,那打开不要关闭吗?好问题,不需要关闭,因为我们这个是服务器,关了还咋服务。

还有一个疑问,当客户端没有发消息的时候,这个服务器在干啥?忙等吗?并没有,还记得我之前说receive方法那里吗,带有阻塞的兄弟,会阻塞等待直到客户端有消息传入。

最后一步,打印日志

前面的是格式,后面的是一一对应的东西,分别打印请求的ip和端口号,还有请求是啥,回应是啥。

源码

package NetWork; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; /** * Created with IntelliJ IDEA. * Description: * User: zhany * Date: 2025-12-14 * Time: 13:04 */ public class UdpEchoServer { //socket是一个可以和网卡通讯的,读就相当于在网卡上收取信息,写就是通过网卡发送 //首先,先定义一个变量用来存放之后的行为 DatagramSocket socket = null; public UdpEchoServer (int port) throws SocketException { //指定一个端口号,让服务器使用 socket = new DatagramSocket(port); } public void start() throws IOException { System.out.println("服务器启动"); //因为服务器需要7*24小时不间断工作,所以套一个while死循环 while (true){ //处理请求的过程分为三步 //1.读取请求并解析 //这一步是创建一个UDP的数据包,传入的字节数组,就是UDP的载荷 DatagramPacket requestPacket = new DatagramPacket(new byte[1024],1024); socket.receive(requestPacket); //把读取到的二进制转成有效的字符串,使用getdata获取到有效的字节数组,getlength获取到有效的长度,再string String request = new String(requestPacket.getData(),0,requestPacket.getLength()); //2.根据请求,计算响应 //因为写的是回显式服务器,所以不用管先 String response = process(request); //3.返回响应值 //因为前面把他转成了字符串,所以现在需要把他转成二进制的要注意最后不是response.length,同时要给出这个 //回应的端口号和ip DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length, requestPacket.getSocketAddress()); socket.send(responsePacket); //打印日志 System.out.printf("[%s : %d] , req: %s , resp: %s\n",requestPacket.getAddress().toString(), requestPacket.getPort(),request,response); } } private String process(String request) { return request; } public static void main(String[] args) throws IOException { UdpEchoServer udpEchoServer = new UdpEchoServer(9090); udpEchoServer.start(); } }

UdpEchoClient

思路

客户端其实和服务器端有点类似,他也没有办法直接操作网卡,所以他也需要寻找一个代理人datagramsocket去帮他开个通话窗口去读写网卡的数据,逻辑也是比较简单的,首先我们知道UDP是无连接的,所以我们需要在构造方法中传入一个源地址和端口号,让我们知道去访问哪个服务器,核心,让用户输入要发送的内容,然后我们需要构建一个数据包载荷,里面把用户输入的全部转成二进制的,需要知道这个有啥和有多长,其次需要知道这个包要去到哪里,哪个端口号,然后发送出去就ok,然后需要创建一个新的数据包(载荷),等待服务器返回的值,然后把返回的二进制解析成为字符串,然后展示出来,结束

第一步

首先创建一个datagramsocket类型的变量,因为这个和服务端的一样,是无法直接操作网卡的,所以也是需要借助这个代理人的,因为UDP是无连接,所以他不知道要去到哪里,这个时候我们就需要告诉他去到哪里,在构造方法中,需要传入访问的IP地址和端口号。


核心方法start

首先让用户输入想要发送的,然后接下里就简单了,把用户输入的直接开始分解,分解成二进制的数据,放到一个数据包中去,注意在创建这个数据包的时候,需要指定传输的ip和端口号,然后发送就行,接着需要创建好一个空的数据包,用来读取服务器返回的值,再把返回来的值解析成字符串,最后打印出来

注意这个“127.0.0.1”是环回IP,无论你本机的真实IP是啥,都是可以进行访问的

这两个程序在同一个电脑上确实是可以进行互传消息的,那如果在两个电脑上呢?

  1. 如果是在同一个局域网的情况下,是可以进行互发消息的
  2. 如果不在同一个局域网下就无法进行发消息

源码

package NetWork; import java.io.IOException; import java.net.*; import java.util.Scanner; /** * Created with IntelliJ IDEA. * Description: * User: zhany * Date: 2025-12-14 * Time: 18:52 */ public class UdpEchoClient { private DatagramSocket socket = null; //因为UDP并不会记录对方是谁,所以要自己保存 private String serverIp; private int serverPort; public UdpEchoClient(String serverIp, int serverPort) throws SocketException { this.serverIp = serverIp; this.serverPort = serverPort; socket = new DatagramSocket(); //这里必须用无参的,因为客户端如果是固定的不太可能,可以是固定但是非常不可能 } public void start() throws IOException { Scanner scanner = new Scanner(System.in); while (true){ System.out.println("请输入你要发送的内容"); if (!scanner.hasNext()){ break; } String request = scanner.nextLine(); //构造数据载荷的同时要注意ip和端口号 DatagramPacket requestPacket = new DatagramPacket(request.getBytes(), request.getBytes().length, InetAddress.getByName(serverIp), serverPort); //发送 socket.send(requestPacket); //接收 DatagramPacket responsePacket = new DatagramPacket(new byte[1024], 1024); socket.receive(responsePacket); //解析 String response = new String(responsePacket.getData(),0,responsePacket.getLength()); System.out.println(response); } } public static void main(String[] args) throws IOException { UdpEchoClient udpEchoClient = new UdpEchoClient("127.0.0.1",9090); udpEchoClient.start(); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/3 1:41:15

AI 数字孪生工厂:西门子与中信特钢的实践,如何降本 11%?

一、行业痛点:特钢制造的降本困局钢铁行业作为重工业支柱,长期面临 "三高两低" 的发展瓶颈:高能耗、高排放、高成本与低效率、低附加值。中信特钢作为全球特钢领军企业,其生产流程涵盖冶炼、连铸、轧制等十余个核心环节…

作者头像 李华
网站建设 2026/3/1 18:42:49

Spring IoC的实现机制是什么?

大家好,我是锋哥。今天分享关于【Spring IoC的实现机制是什么?】面试题。希望对大家有帮助; Spring IoC的实现机制是什么? 超硬核AI学习资料,现在永久免费了! Spring IoC(Inversion of Contro…

作者头像 李华
网站建设 2026/3/3 0:36:10

耐用折叠屏手机推荐:三星Galaxy Z TriFold如何破解“折痕与耐用”难题?

当折叠屏手机从概念产品走向大众市场,消费者最关心的问题之一就是耐用性。毕竟,折叠屏设备多出了复杂的机械结构和柔性屏幕,这些部件在日常使用中面临更多挑战。那么,如今的折叠屏手机在耐用性方面达到了什么水平?三星…

作者头像 李华
网站建设 2026/3/2 15:01:55

前端技术风险防控:以防为主,防控结合

前端技术风险防控:以防为主,防控结合 1. 核心理念:防与控的辩证关系 防:在风险发生前,通过技术手段、流程规范、架构设计等主动预防,从根源上减少风险发生的概率。 控:当风险不可避免地发生时&a…

作者头像 李华
网站建设 2026/3/3 11:19:43

入门大模型必知的100个基础问题(附简明答案)

写在前面 这篇内容将图片中的要点按顺序整理为「100 个基础问题 简明答案」。你可以把它当作查阅清单:从概念、结构、训练、评估到优化与应用,快速过一遍大模型(LLM)最常见的知识点。 100个基础问题什么是大模型? 答案…

作者头像 李华