实现回显服务器(基于UDP)

目录

一.回显服务器的基本概念

二.回显服务器的简单示意图

三.实现回显服务器(基于UDP)必须要知道的API 

1.DatagramSocket

2.DatagramPacket 

3.InetSocketAddress

4.二者区别 

1. 功能职责

2. 核心作用

3. 使用场景流程

四.实现服务器端的主要思路 

代码部分如下

实现服务器端的注意事项 

五.实现客户端的主要思路

实现客户端的注意事项 

六.完整代码 

运行测试结果 


一.回显服务器的基本概念

回显服务器(Echo)可以看成是网络编程中的"hello world",是学习网络编程的入门。简单介绍一下,回显服务器就是服务端收到什么,就给客户端发送什么。我会基于UDP来实现一个回显服务器。

二.回显服务器的简单示意图

三.实现回显服务器(基于UDP)必须要知道的API 

1.DatagramSocket

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

void receive(DatagramPacket p)

   

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

2.DatagramPacket 

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

3.InetSocketAddress

方法签名方法说明
InetSocketAddress(InetAddress addr, int port)创建一个 Socket 地址,包含 IP 地址和端口号

4.二者区别 

1. 功能职责

  • DatagramSocket:是套接字类,相当于 “码头”,负责发送、接收DatagramPacket数据报,还能绑定端口、管理网络连接(虽 UDP 无连接,但它提供收发的基础通道 ),比如通过send发送数据报、receive接收数据报,close关闭套接字。
  • DatagramPacket:是数据报类,相当于 “集装箱”,负责封装 UDP 通信中要发送或接收的数据,包含数据内容、数据长度,以及发送 / 接收时的目标地址(IP + 端口 )或源地址信息。

2. 核心作用

  • DatagramSocket聚焦网络收发操作,决定 “怎么传”(用哪个端口、怎么建立收发通道 );
  • DatagramPacket聚焦数据封装,决定 “传什么”(数据内容 )和 “传给谁 / 从哪收”(地址信息 ) 。

3. 使用场景流程

UDP 通信时,先创建DatagramSocket作为收发的 “通道”,再创建DatagramPacket封装数据 / 地址,最后通过DatagramSocketsend/receive完成数据收发 。比如客户端用DatagramSocket发送封装了数据和目标地址的DatagramPacket;服务器端用DatagramSocket绑定端口,接收包含数据和源地址的DatagramPacket 。

四.实现服务器端的主要思路 

1.读取请求并解析

2.根据请求,计算响应

3.把响应返回给客户端

4.打印日志(方便观察)

代码部分如下

public void start() throws IOException {while(true){//1.读取请求并解析DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);//输出型参数socket.receive(requestPacket);String request=new String(requestPacket.getData(),0,requestPacket.getLength());//2.根据请求,计算响应String response=process(request);//3.把响应返回给客户端DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);//4.打印日志System.out.printf("[%s:%d,request:%s response:%s]\n",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);}}

实现服务器端的注意事项 

五.实现客户端的主要思路

1.在控制台读取用户要输入的内容

2.把请求发送给服务器

3.发送请求数据包给服务器端

4.接收服务器端的响应

5.把从服务器读取的数据进行解析,打印出来

  public void start() throws IOException {Scanner scanner=new Scanner(System.in);while(true){System.out.println("请输入内容");//按ctrl+d会breakif(!scanner.hasNext()){break;}//1。从控制台读取用户要输入的内容String resquest=scanner.next();//2.把请求发送给服务器DatagramPacket resquestPacket=new DatagramPacket(resquest.getBytes(),resquest.getBytes().length,InetAddress.getByName(ServerIp),ServerPort);
//            socket.receive(resquestPacket);//3.发送请求数据包给服务器端socket.send(resquestPacket);//4.接收服务器端的响应DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);//5.把从服务器读取的数据进行解析,打印出来String response=new String(responsePacket.getData(),0,responsePacket.getLength());System.out.println(response);}}

实现客户端的注意事项 

六.完整代码 

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;//记录ip与端口号private String ServerIp;private int ServerPort;//服务器的ip与端口号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("请输入内容");//按ctrl+d会breakif(!scanner.hasNext()){break;}//1。从控制台读取用户要输入的内容String resquest=scanner.next();//2.把请求发送给服务器DatagramPacket resquestPacket=new DatagramPacket(resquest.getBytes(),resquest.getBytes().length,InetAddress.getByName(ServerIp),ServerPort);
//            socket.receive(resquestPacket);//3.发送请求数据包给服务器端socket.send(resquestPacket);//4.接收服务器端的响应DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);//5.把从服务器读取的数据进行解析,打印出来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",1777);udpEchoClient.start();}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;public class UdpEchoServer {private DatagramSocket socket=null;public UdpEchoServer(int port) throws SocketException {socket=new DatagramSocket(port);}public void start() throws IOException {while(true){//1.读取请求并解析DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);//输出型参数socket.receive(requestPacket);String request=new String(requestPacket.getData(),0,requestPacket.getLength());//2.根据请求,计算响应String response=process(request);//3.把响应返回给客户端DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);//4.打印日志System.out.printf("[%s:%d,request:%s response:%s]\n",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);}}//将private改为public,方便方面有新功能,可以进行重写public String process(String request) {return request;}public static void main(String[] args) throws IOException {UdpEchoServer udpEchoServer=new UdpEchoServer(1777);udpEchoServer.start();}
}

运行测试结果 

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

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

相关文章

LabVIEW电液伺服阀自动测试

针对航空航天及工业液压领域电液伺服阀测试需求,采用 LabVIEW 图形化编程平台,集成 NI、GE Druck 等品牌硬件,构建集静态特性(流量/ 压力 / 泄漏)与动态特性(频率响应)测试于一体的自动化系统&a…

性能优化 - 高级进阶: Spring Boot服务性能优化

文章目录 Pre引言:为何提前暴露指标与分析的重要性指标暴露与监控接入Prometheus 集成 性能剖析工具:火焰图与 async-profilerasync-profiler 下载与使用结合 Flame 图优化示例 HTTP 及 Web 层优化CDN 与静态资源加速Cache-Control/Expires 在 Nginx 中配…

力扣网C语言编程题:除自身以外数组的乘积

一. 简介 本文记录力扣网上涉及数组方面的编程题,主要以 C语言实现。 二. 力扣上C语言编程题:涉及数组 题目:除自身以外数组的乘积 给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i…

SpringBoot扩展——发送邮件!

发送邮件 在日常工作和生活中经常会用到电子邮件。例如,当注册一个新账户时,系统会自动给注册邮箱发送一封激活邮件,通过邮件找回密码,自动批量发送活动信息等。邮箱的使用基本包括这几步:先打开浏览器并登录邮箱&…

【html】iOS26 液态玻璃实现效果

<!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>液体玻璃效果演示</title><style>bo…

探索算法秘境:量子随机游走算法及其在图论问题中的创新应用

目录 ​编辑 一、量子随机游走算法的起源与原理 二、量子随机游走算法在图论问题中的创新应用 三、量子随机游走算法的优势与挑战 四、结语 在算法研究的浩瀚星空中&#xff0c;总有一些领域如同遥远星系&#xff0c;闪烁着神秘而诱人的光芒。今天&#xff0c;我们将一同深…

C# 一维数组和矩形数组全解析

在编程的世界里&#xff0c;数组是一种非常重要的数据结构。今天&#xff0c;我们就来详细了解一下一维数组和矩形数组。 数组基础认知 数组实例是从 System.Array 继承类型的对象。由于它从 BCL 基类派生而来&#xff0c;所以继承了许多有用的成员&#xff1a; Rank 属性&a…

WebStorm编辑器侧边栏

目录 编辑器侧边栏行号配置行号隐藏行号 代码折叠侧边栏图标书签添加匿名书签添加助记符书签 运行和调试管理断点配置断点图标 版本控制配置Git Blame注释 编辑器侧边栏 编辑器左侧的垂直区域。当编写代码时&#xff0c;提供重要信息和操作图标。外观和行为可以根据你的喜好进…

腾讯云TCCA认证考试报名 - TDSQL数据库交付运维工程师(PostgreSQL版)

数据库交付运维工程师-腾讯云TDSQL(PostgreSQL版)认证 适合人群&#xff1a; 适合从事TDSQL(PostgreSQL版)交付、运维、售前咨询以及TDSQL(PostgreSQL版)相关项目的管理人员。 认证考试 单选*40道多选*20道 成绩查询 70分及以上通过认证&#xff0c;官网个人中心->认证考…

attn_mask 为 (1, 1) 时什么意思? 7,7又是什么意思?

在深度学习中&#xff0c;特别是在 Transformer 模型和注意力机制&#xff08;Attention Mechanism&#xff09;中&#xff0c;attn_mask&#xff08;注意力掩码&#xff09;是一个用于控制注意力计算的张量。它决定了在计算注意力分数时&#xff0c;哪些位置应该被关注&#x…

Qt联合Halcon开发二:Halcon窗口绑定Qt控件显示Hobject图像【详细图解流程】

1. 项目准备 在本项目中&#xff0c;我们将使用Qt框架与Halcon库结合&#xff0c;展示图像并进行图像处理。首先&#xff0c;确保你已经配置好Qt和Halcon的开发环境。 环境配置可查看上篇文章 2. 创建Qt界面 在Qt中&#xff0c;创建一个窗口并拖入按钮和Graphics View控件。G…

Redis 持久化机制详解:RDB、AOF 原理与面试最佳实践(AOF篇)

在上一章我们深入学习了 Redis 中重要的数据持久化机制 ——RDB&#xff08;Redis Database&#xff09;&#xff0c;了解了其通过周期性快照将数据以二进制文件形式保存到磁盘的原理&#xff0c;包括触发条件、文件结构以及优缺点等核心内容。 Redis 持久化机制详解&#xff…

【GateWay】和权限验证

【GateWay】网关详解和权限验证 一、Gateway 核心概念与架构二、路由断言&#xff08;Route Predicates&#xff09;详解三、过滤器&#xff08;Filters&#xff09;机制四、权限认证的核心理论模型五、Spring Cloud Gateway Security OAuth2 集成方案六、OAuth2.0 集成 一、…

QSqlDatabase: QSQLITE driver not loaded

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言可能的原因解决办法1. 确认 SQLite 驱动插件文件2. 拷贝插件文件到应用程序目录3. 设置插件搜索路径4. 安装 SQLite 依赖库5. 解决 QCoreApplication 实例问题 …

20250619在荣品的PRO-RK3566开发板的Android13下解决海罗光电有限公司HL070T58C-05屏在启动的时候出现白色条纹的问题【时序】

20250619在荣品的PRO-RK3566开发板的Android13下解决海罗光电有限公司HL070T58C-05屏在启动的时候出现白色条纹的问题 2025/6/19 20:39 缘起&#xff1a;荣品的PRO-RK3566开发板的Android13下&#xff0c;点亮海罗光电有限公司HL070T58C-05屏。 在启动的时候会出现花屏/白色条纹…

docker使用Volume对Nginx进行挂载

需求&#xff1a; 需要将Nginx的欢迎页面也就是index.html文件进行修改。 原始方法&#xff1a;由于docker会为每一个容器创建其对应的文件信息&#xff0c;但是创建的信息内容只有其最基础的运行信息&#xff0c;所以想要直接去访问其index.html就无法做到。 使用volume&am…

基于springboot的宠物服务预约系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;没有什么华丽的语言&#xff0…

idea 2025会在用户目录创建IdeaSnapshots文件夹

推荐一个api管理测试工具 一个简单的API测试和编写文档的工具 idea 2025会在用户目录创建IdeaSnapshots文件夹 解决方案 打开 Profiler 点击 setting 参考 https://youtrack.jetbrains.com/articles/SUPPORT-A-1086/How-to-change-or-turn-off-the-IdeaSnapshots-folder-…

【Mini-F5265-OB开发板试用测评】2、PWM驱动遥控车RX2接收解码带马达驱动控制IC

手头有带转向电机和动力电机小车底盘&#xff0c;买了很久一直在吃灰。 最近查了一下小车的驱动IC是富满微的8D420L,是一款传统的RX2接收解码芯片&#xff0c;带马达驱动。 手头没有TX2发送芯片&#xff0c;所以考虑用MCU直接发送PWM直接接入RX2&#xff0c;可能可以驱动。 一…

Tcpdump网络抓包工具详解!

一、简介 tcpdump就是&#xff1a;dump the traffic on a network&#xff0c;根据使用者的定义对网络上的数据包进行截获的包分析工具。 tcpdump是一个用于截取网络分组&#xff0c;并输出分组内容的工具。凭借强大的功能和灵活的截取策略&#xff0c;使其成为类UNIX系统下用…