Java-UDP通讯
利用DatagramSocket发送和接收UDP数据报
public class DatagramSocket
extends Object
implements Closeable此类表示用于发送和接收数据报数据包的套接字。数据报套接字是分组传送服务的发送或接收点。 在数据报套接字上发送或接收的每个数据包都被单独寻址和路由。 从一个机器发送到另一个机器的多个分组可以不同地路由,并且可以以任何顺序到达。
- Java语言中使用数据报(Datagram)进行基于UDP的网络编程;
- Java API中java.net包提供了DatagramSocket和DatagramPacket两个类,用来支持数据报通信;
- DatagramSocket用于在程序之间建立传送数据报的通信连接;
- DatagramPacket则用来表示一个数据报;
- 用数据报方式进行网络编程时,无论客户端还是服务器端都要建立一个DatagramSocket对象,用来接收或发送数据报,然后使用DatagramPacket类对象作为传输数据的载体;
DatagramPacket构造方法说明
public final class DatagramPacket
extends Object该类表示数据报包。数据报包用于实现无连接分组传送服务。仅基于该数据包中包含的信息,每个消息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个分组可能会有不同的路由,并且可能以任何顺序到达。包传送不能保证。
DatagramPacket相当于一个被邮寄的包裹,上面写着收货人的地址,包裹里是所要传递的数据
- DatagramPacket(byte[] buf,int length):
- 以一个字节数组来创建DatagramPacket对象,该对象的作用是接收DatagramSocket中的数据。
- 相当于一个缓冲池的作用
- DatagramPacket(byte buf[], int offset, int length) {} :
- 一个字节的数组来创建DatagramPacket对象,其中 int offset 代表缓冲区的偏移量,int length代表长度/要读取的字节数(也可以说是池子的容量)
- 用于接收长度的分组length ,指定偏移到缓冲器中。length参数必须小于或等于buf.length 。
- buf - 用于保存传入数据报的缓冲区。
- DatagramPacket(byte buf[], int offset, int length, InetAddress address, int port) :
- 创建一个用于发送的DatagramPacket对象,指定发送buf数组中从offset开始,总共length个字节。
-
构造用于发送长度的分组数据报包length具有偏移ioffset指定主机上到指定的端口号。 length参数必须小于或等于buf.length 。
- DatagramPacket(byte[] buf, int length, InetAddress addr, int port):
- 以一个包含数据的数组来创建DatagramPacket对象,创建该DatagramPacket对象时还指定了IP地址和端口--这就决定了该数据报的目的地。
利用DatagramPacket和Datagramsocket简单实现服务器和客户端的通信
- 1、创建客户端
- 1)创建客户端 DatagramSocket 类+指定端口
- 2)准备数据 字节数组
- 3) 打包 DatagramPacket +服务器地址 以及端口
- 4) 发送
- 5) 释放资源
- 2、服务器端
- 1)创建服务器 DatagramSocket 类+指定端口
- 2)准备接受的容器 字节数组 封装 DatagramPacket
- 3)包接收资源
- 4) 分析
- 5) 释放资源 简单来说就是服务器先挖一个DatagramPacket的邮箱,时刻准备着接受邮件,客户端这边准备好所要邮寄的东西,写好所要邮寄的地址(DatagramPacket+服务器地址+端口)不然邮递员不知道把邮件往那发送。
public class Server {
public static void main(String[] args) throws IOException {
//创建DatagramSocket对象,用来接收数据,端口为5000
DatagramSocket serverDatagramSocket = new DatagramSocket(5000);
//定义一个字节数组作为缓存buffer
byte[] buffer = new byte[1024];
//实例化DatagramPacket对象(参数为buffer,偏移量,长度)
DatagramPacket receivePacket = new DatagramPacket(buffer, 0, buffer.length);
System.out.println("开始接收数据");
while (true) {
//接收数据(接收到的字节数据存放到receivePacket对象中) 代码阻塞
serverDatagramSocket.receive(receivePacket);
//解析数据报中的信息,获得主机名及端口、数据等
String addressName = receivePacket.getAddress().getHostName();
int port = receivePacket.getPort();
System.out.println("来自主机:" + addressName + "端口:" + port);
//获取到receivePacket接收到的数据,并转换为字符串
String s = new String(receivePacket.getData(), 0, receivePacket.getLength());
System.out.println("接收的数据:" + s);
}
}
}
import java.io.IOException;
import java.net.*;
/*
发送数据的客户端
*/
public class Client {
public static void main(String[] args) throws IOException {
//构造数据报套接字并将其绑定到本地主机上的指定端口。
DatagramSocket datagramSocket = new DatagramSocket(3456);
String str = "Hello I come from tjetc";
byte[] dataByte = str.getBytes();
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 5000;
DatagramPacket datagramPacket = new DatagramPacket(dataByte,0,dataByte.length,address,port);
//发送数据
datagramSocket.send(datagramPacket);
System.out.println("发送数据:" + str);
}
}
UDP协议通讯的用户状态跟踪
- 和Socket不同,UDP是一个典型的非状态协议(即UDP通讯的两个节点无法获取对方的在线状态),因此在实时通讯领域判定客户端是否掉线就不及Socket方式方便(Socket方式通讯时一端掉线另一端会直接抛出异常)
- 在这种情况下,服务器要想获取客户端的在线信息就需要完成定期问询,如果在规定时间内能够得到客户端自动反馈的问询结果则说明客户端依旧在线,反之则客户端离线(即心跳信息)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)