UDP Socket

前言

UDP是一种不可靠传输 不保证消息的可靠传递,因此有时被称为不可靠的数据报协议

在Java中UDP涉及两个类DatagramSocket 与DatagramPacket

要想理解UDP Socket编程必须要清楚上述两个 类的作用

DatagramSocket 与DatagramPacket

DatagramSocket 用于创建发送或接收数据报包的套接字(用于发送和接收消息)

DatagramPacket 用于表示数据报包本身 (属于是构造消息)

我们 以简单的回响服务器客户端为例

1.UdpEchoServer(服务端)

服务端的构造需要指定端口 这个被指定的端口就是 服务端的监控端口 用于监控是否有客户端请求

服务端的角色是被动连接,只需要在端口上等着 就像一个店铺只需要固定门牌号(端口),不需要知道客人是谁,客人自然会找上门来

1.首先作为服务端要有接收和 发送信息的能力 声明属性DatagramSocket

2.构造服务端 声明端口 以此端口来创建DatagramSocket 实例

3.设置一个request数据包 利用receive方法来获取到客户端发送的消息 为什么说request是输出型参数 ,大家可以类似理解为最初request是空的 但是经过receive函数 request被赋予了值,这个值就是客户端发送的,物理介质就是网卡

4.解析请求内容 获取0到实际数据长度内容

5.根据请求计算响应 此处因为我们是 简单的回响服务器 此处省略处理

6.构造响应,响应以 字节形式 传输,长度,但需注意udp本身不存储双方信息 所以我们需要在数据包中加入发出请求的 目标Ip和目标端口

7.将构造好的响应通过send发送给 客户端

2.UdpEchoClient(客户端)

客户端 的角色是要主动去找 所以必须要知道 自己要去哪 IP 和 端口

就像你去吃饭必须知道餐厅的地址和门牌号,否则你根本不知道该去哪

1.DatagramSocket不指定端口 是因为它不需要去指定标识 在运行时操作 系统会为他自动分配一个临时 端口 所以我们不建议在DatagramSocket中指定端口 由于服务端端口时是它 的标识和门牌号 所以它必须去创建门牌实例 此处则不需要

2.构造DatagramPacket 数据包去发送给服务端 数据包中要加入消息的字节化数据 和目标Ip 和目标 端口 表明这是你信息要发送的位置

3.仍然是输出型参数 先 声明一个空的 response 在receive中再从网卡中读取到服务端 的响应 然后赋给response

4.解析响应有效字节数据

疑问点:

为什么服务端要指定DatagramSocket端口?

因为 服务端要设定一个 门牌号 这样客户端发送信息时,就可以用来监控请求 而客户端操作系统会自动为客户端的DatagramSocket分配端口号,因为没有必要去指定端口 发送信息时客户端的IP 和端口会被包装在数据包中,服务端就直接可以通过数据包解析出 客户端的Ip和端口号

具体的通信过程?

服务端 有一个端口号相当于门牌 表明位置

客户端 通过你手动代码去提供 服务端 的IP 和端口, 客户端本身IP和端口号操作系统会自动分配端口 发送信息时将自身IP和 端口包装在数据包中

服务端收到客户端 的信息后 ,就通过数据包中的ip和端口 将响应发送给客户端

源代码:

UdpEchoServer

java 复制代码
public class UdpEchoServer {

    private DatagramSocket datagramSocket;

    public UdpEchoServer(int port) throws SocketException {
        //指定一个端口号来使用 此端口用于监控请求
        this.datagramSocket=new DatagramSocket(port);
    }
    public void start() throws IOException {
        //启动服务器
        System.out.println("服务器启动");
        while(true) {
            //1.获取客户端请求并解析
            //先设置一个空的request
            DatagramPacket request=new DatagramPacket(new byte[4096],4096);
            //从网卡中获取 到request的内容 输出到request中(输出型参数)
            datagramSocket.receive(request);
            //解析请求 获取到请求内容
            String words=new  String(request.getData(),0,request.getLength());
            //2.根据请求计算响应
            String key=process(words);
            //3.返回响应给客户端
            DatagramPacket response=new DatagramPacket(key.getBytes(),0,
                    key.getBytes().length,request.getAddress(), request.getPort());
            datagramSocket.send(response);
           //打印数据报发送成功
            System.out.println("key 成功发送"+key);
        }
    }

    private String process(String words) {
        return words;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoServer server=new UdpEchoServer(8888);
        server.start();
    }
}

UdpEchoClient

java 复制代码
public class UdpEchoClient {
     private int port;
     private String serverIp;
     private DatagramSocket datagramSocket;
     public UdpEchoClient(int port,String  server) throws SocketException {
         this.port=port;
         this.serverIp=server;
         this.datagramSocket=new DatagramSocket();
     }
     public void start() throws IOException {
         //客户端 服务启动
         System.out.println("客户端服务启动");
         while(true){
             Scanner  sc=new Scanner(System.in);
             System.out.println("请输入:");
             String key=sc.next();
             //1.构造DatagramPocket数据报发送消息
             DatagramPacket  request=new DatagramPacket(key.getBytes(),0,
                     key.getBytes().length,InetAddress.getByName(serverIp),port);
             datagramSocket.send(request);
             //接收服务器的响应
             DatagramPacket  response=new DatagramPacket(new byte[4096],4096);
             datagramSocket.receive(response);
             //解析响应内容
             String words=new String(response.getData(),0,response.getLength());
             System.out.println(words);
             System.out.println("解析成功");
         }
     }

    public static void main(String[] args) throws IOException {
        UdpEchoClient client=new UdpEchoClient(8888,"127.0.0.1");
        client.start();
    }

}
相关推荐
byte轻骑兵4 小时前
【HID】规范精讲[7]: 蓝牙HID底层核心——基带与LMP依赖深度解析
网络·人工智能·人机交互·蓝牙·键盘·hid
RunningBComeOn4 小时前
为什么无法抓取到http之间的明文传输
网络·网络协议·http
KKKlucifer5 小时前
纵深防御视角下安全运维服务体系构建思路
运维·网络·安全
lbb 小魔仙5 小时前
2026远程办公软件夏季深度横测:ToDesk、向日葵、网易UU远程全面对比,远控白皮书
android·服务器·网络协议·tcp/ip·postgresql
2501_915921435 小时前
HTTPS前端劫持 新一代流量劫持解决方案
前端·网络协议·ios·小程序·https·uni-app·iphone
Andya_net5 小时前
网络安全 | TCP三次握手与四次挥手
网络·tcp/ip·web安全
志栋智能5 小时前
超自动化安全:数字时代的网络免疫系统
网络·安全·自动化
叶帆5 小时前
【YFIOs】从传感芯片到表格曲线
网络
上海云盾-小余6 小时前
TCP 碎片攻击深度剖析:漏洞成因、流量甄别与高防加固实操方案
网络·网络协议·tcp/ip
ZStack开发者社区6 小时前
ZStack Cloud 5.5.16正式发布
网络·云计算·智能路由器