使用socket实现UDP版的回显服务器

news/2025/1/11 6:59:20/

文章目录

  • 1. Socket简介
  • 2. DatagramSocket
  • 3. DatagramPacket
  • 4. InetSocketAddress
  • 5. 实现UDP版的回显服务器

在这里插入图片描述

1. Socket简介

Socket(Java套接字)是Java编程语言提供的一组类和接口,用于实现网络通信。它基于Socket编程接口,提供了一种简单而强大的方式来实现网络应用程序。

ocket类库提供了丰富的方法和功能,用于处理网络通信的各个方面。它支持TCP和UDP协议,可以实现可靠的、面向连接的通信(TCP)或不可靠的、无连接的通信(UDP)。Java Socket还提供了一些高级功能,如多线程处理、异步通信、加密通信等,以满足不同网络应用的需求。

本文主要使用Socket实现UDP版的客户端和服务器

  • DatagramSocket 是UDP Socket,用于发送和接收UDP数据报。

  • DatagramPacket是UDP Socket发送和接收的数据报。

2. DatagramSocket

DatagramSocket是Java网络编程中用于实现UDP协议的类。它是基于Socket类的子类,用于发送和接收UDP数据报。

DatagramSocket 的构造方法:

方法说明
DatagramSocket()创建一个UDP数据报套接字的socket,绑定本机任意一个随机端口(一般用户客户端)
DatagramSocket(int port)创建一个UDP数据套接字的socket,绑定指定的port端口(一般用于服务端)

DatagramSocket的常用方法如下:

方法说明
void receive(DatagramPacket p)从此套接字接收数据报,如果没有接收到数据报,会阻塞等待
void send(DatagramPacket p)从此套接字发送数据包
void close()关闭数据报套接字

3. DatagramPacket

DatagramPacket是Java网络编程中用于封装和解析UDP数据报(Datagram)的类。它用于在DatagramSocket中发送和接收UDP数据报

DatagramPacket的构造方法:

方法说明
DatagramPacket(byte[] buf, int length)构造一个DatagramPacket以用来接收数据报,接收的数据保存在 字节数组(第一个参数buf)中,接收指定长度(第二个参数 length)
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)构造一个DatagramPacket以用来发送数据报,发送的数据为字节 数组(第一个参数buf)中,从0到指定长度(第二个参数 length)。address指定目的主机的IP和端口号

DatagramPacket的常用方法:

方法说明
InetAddress getAddress()从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取 接收端主机IP地址
int getPort()从接收的数据报中,获取发送端主机的端口号;或从发送的数据报中,获取接收端主机端口号
byte[] getData()获取数据报中的数据

4. InetSocketAddress

InetSocketAddress是Java网络编程中用于表示IP地址和端口号的类。它是SocketAddress类的子类,用于在网络通信中指定主机的地址和端口。

简单介绍一下InetSocketAddress的构造方法:

InetSocketAddress(InetAddress addr,int port)创建一个Socket地址,包含IP地址和端口号

5. 实现UDP版的回显服务器

回显服务器(Echo Server)是一种简单的网络服务器应用,它接收客户端发送的数据,并将接收到的数据原样返回给客户端。

客户端代码:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;public class UdpEchoClient {private DatagramSocket socket = null;private String serverIp;private int serverPort;public UdpEchoClient(String serverIp, int serverPort) throws SocketException {socket = new DatagramSocket(serverPort);this.serverIp = serverIp;this.serverPort = serverPort;}public void start() throws IOException {System.out.println("客户端上线!");Scanner scanner = new Scanner(System.in);while (true) {// 读取用户输入的内容System.out.println("-> ");String request = scanner.next();// 构造 UDP请求,并发送给服务器DatagramPacket reqPacket = new DatagramPacket(request.getBytes(), request.getBytes().length,InetAddress.getByName(this.serverIp), this.serverPort);socket.send(reqPacket);// 从服务器读取响应DatagramPacket respPacket = new DatagramPacket(new byte[4096], 4096);socket.receive(respPacket);String resp = new String(respPacket.getData(), 0, respPacket.getLength());}}public static void main(String[] args) throws IOException {UdpEchoClient echoClient = new UdpEchoClient("127.0.0.1", 6666);echoClient.start();}
}

服务器代码:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;public class UdpEchoServer {private DatagramSocket socket = null;// port 为服务器要绑定的端口public UdpEchoServer(int port) throws SocketException {socket = new DatagramSocket(port);}/*** 服务器启动方法*/public void start() throws IOException {System.out.println("服务器启动!");while (true) {// 读取请求并解析DatagramPacket reqPacket = new DatagramPacket(new byte[4096], 4096);socket.receive(reqPacket);// 解析请求String req = new String(reqPacket.getData(), 0, reqPacket.getLength());// 计算响应String resp = process(req);// 将响应返回给客户端DatagramPacket respPacket = new DatagramPacket(resp.getBytes(), resp.getBytes().length,reqPacket.getSocketAddress());socket.send(respPacket);// 打印日志System.out.printf("[%s:%d] req: %s;resp: %s\n", reqPacket.getSocketAddress().toString(),reqPacket.getPort(), req, resp);}}/*** 根据请求计算响应* 因为是 回显服务器,直接返回即可** @param req*/private String process(String req) {return req;}public static void main(String[] args) throws IOException {UdpEchoServer echoServer = new UdpEchoServer(6666);echoServer.start();}
}

运行流程:
在这里插入图片描述

运行结果:

在这里插入图片描述

在这里插入图片描述

另外服务器是给多个客户端提供服务器的,IDEA默认是无法启动多个客户端的,因此手动设置

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


http://www.ppmy.cn/news/1003888.html

相关文章

Vue3_03_setup函数

1.理解:Vue3.0 中的一个新的配置项,值为一个函数。 2.setup是所有组合式 API 表演的舞台。 3.组件中所用到的:数据、方法等等,均要配置在setup中。 4.setup函数的两种返回值: 若返回一个对象,则对象中的…

【大数据】Flink 从入门到实践(一):初步介绍

Flink 从入门到实践(一):初步介绍 Apache Flink 是一个框架和分布式处理引擎,用于在 无边界 和 有边界 数据流上进行 有状态 的计算。Flink 能在所有常见集群环境中运行,并能以内存速度和任意规模进行计算。 1.架构 1…

51单片机学习-AT24C02数据存储秒表(定时器扫描按键数码管)

首先编写I2C模块,根据下面的原理图进行位声明: sbit I2C_SCL P2^1; sbit I2C_SDA P2^0;再根据下面的时序结构图编写函数: /*** brief I2C开始* param 无* retval 无*/ void I2C_Start(void) {I2C_SDA 1; I2C_SCL 1; I2C_SDA 0;I2C_S…

【采用有限元法技术计算固有频率和欧拉屈曲荷载】使用有限元法的柱子的固有频率和屈曲荷载(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【iOS】锁

线程安全 当一个线程访问数据的时候,其他的线程不能对其进行访问,直到该线程访问完毕。简单来讲就是在同一时刻,对同一个数据操作的线程只有一个。而线程不安全,则是在同一时刻可以有多个线程对该数据进行访问,从而得…

腾讯云COS+PicGO+截图工具+Obsidian+Typora+蚁小二:打造丝滑稳定的Markdown写作和分发环境

目录 背景 工具说明 腾讯云COS PicGO图片上传工具 截图工具 Obsidian Typora 蚁小二 首次配置完整演示步骤 腾讯云COS PicGO图片上传工具 截图工具 Obsidian Typora 蚁小二 使用总结(简单又丝滑的编辑步骤) 背景 很久很久以前&#xff…

Excel·VBA表格横向、纵向相互转换

如图:对图中区域 A1:M6 横向表格,转换成区域 A1:C20 纵向表格,即 B:M 列转换成每2列一组按行写入,并删除空行。同理,反向操作就是纵向表格转换成横向表格 目录 横向转纵向实现方法1转换结果 实现方法2转换结果 纵向转横…

嵌入式存储器为AI的实现提供了实现架构

近年来,大脑启发式计算机领域的研究活动获得了巨大的发展。主要原因是试图超越传统的冯诺依曼架构的局限性,后者越来越受存储器-逻辑通信的带宽和等待时间的局限性的影响。在神经形态架构中,内存是分布式的,可以与逻辑共定位。鉴于…