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

javaEE-网络编程-3 UDP

目录

Socaket套接字 

UDP数据报套字节编程

1.DatagrameSocket类

DatagramSocaket构造方法:

DatagramSocaket常用方法:

2.DatagramPacket类

DatagramPacket构造方法:

UDP回显服务器实现

UDP服务端实现:

创建一个Socket类对象:

构造方法:

创建start()方法:

异常:

代码展示:

UDP客户端实现:

创建一个Socket对象:

构造方法:

start()方法:

​编辑 代码展示:

 结果:

服务端和客户端之间的执行流程:


Socaket套接字 

Socaket套接字是系统提供的,用于网络通信的技术。是基于TCP/IP协议的网络通信的基本单位。

基于Socaket套接字的网络程序开发就是网络编程。

简单来说,Socket就是操作系统中的一个概念,本质上是一种特殊的文件。

Socaket就是把“网卡”这样的概念给抽象成了文件,把网络通信和文件操作给统一了:

往Socket中写数据,就相当于通过网卡发送数据;从Socket中读数据,就相当于通过网卡接收数据。

Socaket套接字注意事项:

1. 客⼾端和服务端:开发时,经常是基于⼀个主机开启两个进程作为客⼾端和服务端,但真实的场 景,⼀般都是不同主机。

2. 注意 ⽬的IP 和 ⽬的端⼝号,标识了⼀次数据传输时要发送数据的终点主机和进程。

 3. Socket编程我们是使⽤  流套接字 和 数据报套接字,基于传输层的TCP或UDP协议,但应⽤层协议, 也需要考虑,这块我们在后续来说明如何设计应⽤层协议。

4. 关于端⼝被占⽤的问题

5. 如果⼀个进程A已经绑定了⼀个端⼝,再启动⼀个进程B绑定该端⼝,就会报错,这种情况也叫端⼝ 被占⽤

UDP数据报套字节编程

对于UDP来说,是无连接,面向数据报的特点。即每次都没有建立连接,并且一次发送全部的数据报,一次也接受全部的数据报。

UDP的socktet的api是如何实现的?

java中是由UDP协议通信,主要是使用DatagramSocket类来创建数据报套接字Socket。用DatapramPacket类来作为发送和接收数据报。

1.DatagrameSocket类

java中就是用DatagrameSocket 类来表示UDP Socket文件,用于接收和发送UDP数据报.

DatagramSocaket构造方法:

DatagramSocaket常用方法:

receive和send方法的 DatagramPacket 参数属于 “输出型参数”。

2.DatagramPacket类

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

使用这个类来表示UDP数据报,每次传输数据都要以UDP数据报为单位。

DatagramPacket构造方法:

DatagramPacket常用方法:

创建UDP发送数据DatagramPacket responseSocket时,需要指定发送的对方IP和端口号,要传入SocketAddress参数:目的主机的IP地址和端口号,该对象可以使用InteSocketAddress类来创建。

InteSocketAddress类

构造方法:

UDP回显服务器实现

写一个简单的UDP 服务器/客户端通信的程序 :回显服务器(Echo Server)

这个程序没有实现什么功能,就是调用Socket api,让客户端给服务器发送一个请求,请求就是从控制台输入的字符串,服务器再将这个字符串返回给客户端,客户端再将字符串打印显示出来。

DatagramSocket,DatagramPacket类都是再java.net包中的·:

服务器和客户端要创建一个Socket对象,服务器的Socket要显示指定一个端口号,而客户端Socket不需要显示指定(系统会自动分配一个随机端口号)

原因:

UDP服务端实现:

创建一个Socket类对象:

构造方法:

显示指定一个端口号

创建start()方法:

完成Socket的 接收客户端请求,做出响应 返回响应的功能,并循环执行

任务1.创建一个DatagramPacket类对象,接收用户的请求,调用receive方法

requestPacket:

任务2:根据请求 计算响应

任务3:将响应返回给客户端

responsePacket:

这里的第三个参数response.getBytes().length.不能写成response.length():

异常:

在这个程序中,会经常看到SockerException和IOException,要处理一下:

start()代码:

代码展示:

UdpEchoServer

/**
 * 实现UDP 回显服务器
 */

class UdpEchoServer{
    //创建DatagramSocket类,进行发送数据和接收数据
    private DatagramSocket socket=null;
    //UDP服务端 构造方法 serverPock: 指定端口号
    public UdpEchoServer(int serverPort) throws SocketException {
        socket=new DatagramSocket(serverPort);
    }
    //start方法中,完成Socket的 接收客户端请求,做出响应 返回响应的功能
    public void start() throws IOException {
        System.out.println("服务器启动");
        while(true){//每次循环 ,就是处理一个请求-响应的过程
            //1.创建一个DatagramPacket类空对象,用来接收用户的请求
            DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);
            //通过receive接收用户的请求
            //此处可能会出现阻塞-》等待用户发送请求
            socket.receive(requestPacket);
            //2.根据请求 计算响应
            //先将请求转换成字符串 方便后面的操作
            String request=new String(requestPacket.getData(),0,requestPacket.getLength());
            //计算响应
            String response=process(request);
            //3.将响应返回给客户端
            //先将响应打包成DatagramPacket, 指定数据内容、长度、要发给哪个客户端
            DatagramPacket responsePacket=new DatagramPacket(response.getBytes(), 0,response.getBytes().length,
                                            requestPacket.getSocketAddress());
           //将响应返回给客户端
            socket.send(responsePacket);
            //打印用户IP 端口号,请求信息 响应信息
            System.out.printf("[%s,%d],req:%s,resp:%s\n",requestPacket.getAddress(),requestPacket.getPort(),
                                                            request,response);
        }
    }

    public String process(String request) {
        //这里什么也不做,就将用户的请求返回
        return request;
    }
    //测试
    public static void main(String[] args) throws IOException {
        UdpEchoServer udpEchoServer = new UdpEchoServer(9090);
        udpEchoServer.start();
    }
}

UDP客户端实现:

创建一个Socket对象:

构造方法:

start()方法:

 代码展示:


/**
 * 实现UDP 回显服务器
 * 客户端
 */

class UdpEchoClient1{
    private DatagramSocket socket=null;
    private String serverIP;//服务端IP
    private int serverPort;//服务端 端口号
    //构造方法 传入服务端的Ip 端口号 并保存
    public UdpEchoClient1(String serverIp,int serverPort) throws SocketException {
        socket=new DatagramSocket();
        this.serverIP=serverIp;
        this.serverPort=serverPort;
    }
    public void start() throws IOException {
        System.out.println("客户端启动");
        Scanner scan=new Scanner(System.in);
        while(true){
            System.out.print("->");
            //1.用户从控制台输入请求
            if(!scan.hasNext()){
                break;
            }
            //2.读取请求
            String request=scan.next();
            //3.将请求发送给服务器
            //先将请求打包成requestPacket , 指定内容,长度 ;指定要发送的服务器IP,端口号
            DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,
                                                            InetAddress.getByName(serverIP),serverPort);
            //发送请求 给服务器
            socket.send(requestPacket);
            //4.接收服务器的响应
            //先创建一个空的DatagramPacket,用来接收服务器的响应
            DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);
            //接收服务器响应
            socket.receive(responsePacket);
            //将响应转换成String 打印在控制台
            String response=new String(responsePacket.getData(),0,responsePacket.getLength());
            System.out.println(response);
        }
    }

    public static void main(String[] args) throws IOException {
        UdpEchoClient1 udpEchoClient1 = new UdpEchoClient1("127.0.0.1", 9090);
        udpEchoClient1.start();
    }
}

 结果:

客户端和服务端同时启动

DatagramPacket对象,共出现了三种形式:

1.创建空对象,用来存放请求的  参数:字节数组 数组长度

2.服务器 存放请求的响应结果  参数:  响应字节数组  数组长度  客户端IP和端口号

3.客户端 向服务端发送请求  参数:  请求字节数组  数组长度  服务端IP  服务端端口号

服务端和客户端之间的执行流程:

通过UDP服务端模拟实现一个"翻译词典":

参考代码:


/**
 * 实现一个词典翻译服务器
 * 英 译 汉
 */
class UdpDirectServer extends UdpEchoServer{
    //翻译服务器,连接功能与初始的服务器一样,通过继承UdpEchoServer类,
    // 重写process方法,实现特有功能
    //创建一个哈希表,通过键值对来实现一个查找的功能
    private HashMap<String,String> hashMap=new HashMap<>();
    public UdpDirectServer(int serverPort) throws SocketException {
        super(serverPort);
        //填充哈希表
        hashMap.put("cat","小猫");
        hashMap.put("dog","小狗");
        hashMap.put("pig","小猪");
        hashMap.put("flag","小鸟");
        //......
        //真实的翻译词典也是通过大量的键值对来实现查找功能的
    }
    //重写父类的process方法,实现"翻译"功能
    @Override
    public String process(String request) {
        return hashMap.get(request);
    }

    public static void main(String[] args) throws IOException {
        UdpDirectServer udpDirectServer = new UdpDirectServer(9090);
        udpDirectServer.start();
    }

}

参考结果:


http://www.kler.cn/a/469141.html

相关文章:

  • Qt 下位机串口模拟器
  • Debian、Ubuntu 22.04和ubuntu 24.04国内镜像源(包括 docker 源)
  • 【微服务与K8S】
  • 什么样的人适合从事FPGA开发的工作?
  • 封装/前线修饰符/Idea项目结构/package/impore
  • 跨站脚本攻击(XSS)详解
  • LabVIEW 实现自动对焦的开发
  • 编译与汇编
  • kubelet状态错误报错
  • linux 逻辑卷挂盘
  • F.interpolate函数
  • [Linux]redis5.0.x升级至7.x完整操作流程
  • 使用MySQL APT源在Linux上安装MySQL
  • spring mvc源码学习笔记之五
  • 【华为OD-E卷 - 九宫格按键输入 100分(python、java、c++、js、c)】
  • Linux系统常用命令详解
  • 怎么找回电脑所有连接过的WiFi密码
  • 【论文阅读笔记】LTX-Video: Realtime Video Latent Diffusion
  • 如何让编码更加高效专注?——程序员编程选明基 RD280U显示器
  • Django Swagger文档库drf-spectacular
  • 【Rust 知识点杂记】
  • 微信小程序提示 miniprogram-recycle-view 引入失败
  • leetcode hot 100 最长递增子序列
  • 智能体语言 Shire 1.2 发布:自定义多文件编辑、Sketch 视图、流式 diff、智能上下文感知...
  • AI生成PPT,效率与创意的双重升级
  • 【开源免费】基于SpringBoot+Vue.JS精品在线试题库系统(JAVA毕业设计)