当前位置: 首页 > news >正文

实现回显服务器(基于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();}
}

运行测试结果 

相关文章:

  • 自定义 eslint 规则
  • PDF转Markdown基准测试
  • SKUA-GOCAD入门教程-第八节 线的创建与编辑3
  • uniapp的app项目,在华为pad上运行,页面显示异常
  • Odoo 如何系统地管理产品从概念设计到废弃淘汰的全过程
  • pycharm 2025.1.1-专业版jupyter notebook远程连接
  • 从STM32到NXP:GPIO就像装修房子,多了个“智能开关”
  • RabbitMQ的交换机和队列概念
  • 前端面试专栏-主流框架:7. React核心概念(组件、JSX、状态管理)
  • 从数据孤岛到智能决策:数据编排如何重构企业数据架构?
  • Java重构实战:小步快跑的高效策略分析
  • 创客匠人:AI重构知识IP定位与变现效率新范式
  • 浏览器读取图片的元数据XMP
  • langchain从入门到精通(七)——利用回调功能调试链应用 - 让过程更透明
  • 如何在 Elementary OS 上安装 Snap Store
  • HarmonyOS 5鸿蒙多端编译实战:从Android/iOS到HarmonyOS 5 的跨端迁移指南详
  • 【Unity】MiniGame编辑器小游戏(一)俄罗斯方块【Tetris】
  • Python 自动化测试/脚本
  • 使用 vscode 开发 uni-app 项目时如何解决 manifest.json 文件注释报错的问题
  • Java-46 深入浅出 Tomcat 核心架构 Catalina 容器全解析 启动流程 线程机制
  • 广告设计公司企业文化/新网站 seo
  • 站长统计向日葵app下载/关键词下载
  • 集团定制网站建设公司/班级优化大师app下载学生版
  • 如何设计一个完整的网站/如何做网络推广
  • hfs网络文件服务器可以做网站/郑州seo哪家专业
  • 宝鸡市城乡住房建设局网站/天津优化网络公司的建议