<JavaEE> 基于 UDP 的 Socket 通信模型

news/2024/5/18 15:13:46 标签: udp, 网络, java-ee

目录

一、认识相关API

1)DatagramSocket

2)DatagramPacket

3)InetSocketAddress

二、UDP数据报套接字通信模型概述

三、回显客户端-服务器通信

1)服务器代码

2)客户端代码


一、认识相关API

1)DatagramSocket

DatagramSocket 常用构造方法
DatagramSocket()创建UDP数据报Scoket套接字,绑定本机任意端口(通常用于客户端)。
DatagramSocket(int port)创建UDP数据报Scoket套接字,绑定本机指定端口(通常用于服务器)。
DatagramSocket 常用方法
void receive(DatagramPacket p)接收数据报并写入参数p中,没有收到则会阻塞等待。
void send(DatagramPacket p)发送数据报。
void close()关闭socket套接字。

2)DatagramPacket

DatagramPacket 用构造方法
DatagramPacket(byte[] buf, int length)构造用于存储数据报的容器,指定字节数组和数组长度。
DatagramPacket(byte[] buf,  int length, SocketAddress address)构造用于存储数据报的容器,指定字节数组、数组长度、目的地IP地址和端口号。
DatagramPacket 常用方法
InetAddress getAddress()从数据报中获取目的地的IP地址。
int getPort()从数据报中获取目的地的端口号。
byte[] getData()从数据报中获取字节数据。

3)InetSocketAddress

InetSocketAddress是SocketAddress的子类。
InetSocketAddress 用构造方法
InetSocketAddress(String ip, int port)构造Socket地址,包含IP地址和端口号。
InetSocketAddress(InetAddress addr, int port)构造Socket地址,包含IP地址和端口号。

二、UDP数据报套接字通信模型概述

UDP协议具有无连接,面向数据报的特征。每次通信,双方都是没有建立连接的,并且一次性发送或接收全部通信内容。
UDP通信,使用DatagramSocket类构建套接字,使用DatagramPacket类构建数据报。
UDP通信流程:客户端构造请求->发出请求->服务器接收请求->解析请求->处理请求->构造响应->返回响应->客户端接收响应->解析响应->处理响应

三、回显客户端-服务器通信

1)服务器代码

public class UDP_Echo_Server {
    private DatagramSocket socket = null;

    public UDP_Echo_Server(int port) throws SocketException {
        //作为服务器端,根据指定端口号创建一个数据报连接通道;
        socket = new DatagramSocket(port);
    }

    //调用该方法启动服务器;
    public void start() throws IOException {
        System.out.println("服务器启动!");
        while(true){
            //新建一个数据报容器,用于存放请求;
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
            //接收数据报(请求),如果暂时没有请求,则在这里阻塞等待;
            socket.receive(requestPacket);
            //将获得的数据报(请求)转换为字符串;
            String request = new String(requestPacket.getData(),0, requestPacket.getLength());
            //通过process方法对请求报进行处理,并形成响应;
            String response = process(request);
            //将响应转换为数据报,数据包中已经指定了目的地IP;
            DatagramPacket responsePacket = new DatagramPacket(
                    response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());
            //将数据报(响应)发送;
            socket.send(responsePacket);
            //打印日志;
            System.out.printf("[%s,%d] req=%s res=%s\n",
                    requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);
        }
    }

    private String process(String request) {
        return request;
    }
    
    public static void main(String[] args) throws IOException {
        UDP_Echo_Server server = new UDP_Echo_Server(端口号);
        server.start();
    }
}

2)客户端代码

public class UDP_Echo_client {
    private DatagramSocket socket = null;
    private String serverIP = "";
    private int serverPort = 0;

    public UDP_Echo_client(String IP,int Port) throws SocketException {
        //作为客户端,需要显式知道服务器的IP和端口号;
        this.serverIP = IP;
        this.serverPort = Port;
        //客户端自己的端口号,由系统自行分配即可,根据系统分配的端口号创建一个数据报连接通道;
        socket = new DatagramSocket();
    }

    //调用该方法启动客户端;
    public void start() throws IOException {
        System.out.println("客户端启动!");
        Scanner sc = new Scanner(System.in);

        while (true){
            System.out.print("->");
            String request = sc.next();

            //将字符串转换为数据报(请求),并在数据报中指定了目的地IP及端口;
            DatagramPacket requestPacket = new DatagramPacket(
                    request.getBytes(),request.getBytes().length,
                    new InetSocketAddress(serverIP,serverPort));
            //发送数据报(请求);
            socket.send(requestPacket);
            //新建一个数据报容器,用于存放响应;
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);
            //接收数据报(响应),如果暂时没有响应,则在这里阻塞等待;
            socket.receive(responsePacket);
            //将获得的数据报(响应)转换为字符串;
            String response = new String(responsePacket.getData(),0,responsePacket.getLength());
            //打印响应;
            System.out.println(response);
        }
    }

    public static void main(String[] args) throws IOException {
        UDP_Echo_client client = new UDP_Echo_client(IP地址,端口号);
        client.start();
    }
}

阅读指针 -> 《TCP回显服务器》

​​​​​​​链接生成中........


http://www.niftyadmin.cn/n/5281000.html

相关文章

Grafana高可用-LDAP

一. grafana高可用 1. 迁移之前的 grafana sqlitedump.sh #!/bin/bash DB$1 TABLES$(sqlite3 $DB .tables | sed -r s/(\S)\s(\S)/\1\n\2/g | grep -v migration_log) for t in $TABLES; doecho "TRUNCATE TABLE $t;" done for t in $TABLES; doecho -e ".mode…

R-列表、矩阵、数组转化为向量

目录 一、c()函数 二、unlist()函数 一、c()函数 c():对应的英文是combine. 当你使用c()函数时,它会将输入的对象连接成一个向量。因此,无论输入是矩阵、数组还是列表,c()函数都会将它们连接成一个简单的向量。因此&#xff…

uniapp使用colorUI

colorUI 微动画 | ColorUI 使用文档 1&#xff1a;把colorui里三个文件复制到自己项目中去 App.vue </script> <style> import url(colorui/icon.css); import url(colorui/main.css); import url("colorui/animation.css");-webkit-keyframes show {…

webpack学习-7.创建库

webpack学习-7.创建库 1.暴露库1.1概念1.2验证1.2.1 不导出方法1.2.2 导出方法 2.外部化 lodash3.外部化的限制4.最终步骤5.使用自己的库5.1坑 6.总结 1.暴露库 这个模块学习有点坑。看名字就是把自己写的个包传到npm&#xff0c;而且还要在项目中使用到它&#xff0c;支持各种…

Python生成圣诞节词云-代码案例剖析【第17篇—python圣诞节系列】

文章目录 ❄️Python制作圣诞树词云-中文&#x1f42c;展示效果&#x1f338;代码&#x1f334;代码剖析 ❄️Python制作圣诞树词云-英文&#x1f42c;展示效果&#x1f338;代码&#x1f334;代码剖析 &#x1f385;圣诞节快乐&#xff01; ❄️Python制作圣诞树词云-中文 &a…

前端 JS 安全对抗原理与实践

作者&#xff1a;vivo 互联网安全团队- Luo Bingsong 前端代码都是公开的&#xff0c;为了提高代码的破解成本、保证JS代码里的一些重要逻辑不被居心叵测的人利用&#xff0c;需要使用一些加密和混淆的防护手段。 一、概念解析 1.1 什么是接口加密 如今这个时代&#xff0c;…

easyexcel完成复杂表头及标题的导出功能

使用easyexcel完成复杂表头及标题的导出功能(自定义样式及多sheet导出) 如需客户端指定excel版本,只需要判断后缀名然后在controller中的.excelType(ExcelTypeEnum.XLS)做指定输出内容格式即可 ***(注意表格行高列宽统一设置是在实体类的类名注解上,如果需要对表格进行精细的…

计算机网络 应用层上 | 域名解析系统DNS 文件传输协议FTP,NFS 万维网URL HTTP HTML

文章目录 1 域名系统DNS1.1 域名vsIP&#xff1f;1.2 域名结构1.3 域名到IP的解析过程域名服务器类型 2 文件传送协议2.1 FTP 文件传输协议2.2 NFS 协议2.3 简单文件传送协议 TFTP 3 万维网WWW3.1 统一资源定位符URL3.2 超文本传送协议HTTP3.2.1 HTTP工作流程3.2.2 HTTP报文结构…