14.Java实现UDP通信

1.关键API

java.net包里提供了实现网络应用程序的类。
在Java中,我们可以使用DatagramSocket来创建UDP服务器,使用DatagramPacket来装载接受的数据。
DatagramSocket这个类是用来发送和接收数据包的套接字类。

发送数据包用的方法是: DatagramSocket.send(DatagramPacket p)
接收数据包用的方法是: DatagramSocket.receive(DatagramPacket p)

DatagramPacket这个类是用来存储数据的数据包。
一般的用法如下:

//其中data是数据字节数组,address是目标地址,port是目标端口号
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);

1.1 UDP报文格式

首先要知道UDP是一种无连接的传输层协议。与TCP不同的是,UDP不保证数据完整无误的发送给目标,而是通过IP层的最大努力机制来传递数据的。

每个UDP报文分别由UDP报文头和UDP数据区两部分组成。
其中UDP报文头有8个字节:
源端口(2字节)+目的端口(2字节)+报文长度(2字节)+校验值(2字节)
UDP数据区长度可变,根据报文长度不同而不同。
在这里插入图片描述

2.实例Demo

2.1 UDPServer

package InternetCode.Udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

/*
 * 服务器端,实现基于UDP的用户登陆
 */
public class UDPServer {//公共类
    public static void main(String[] args) throws IOException {//主程序入口
        /*
         * 接收客户端发送的数据
         */
        // 1.创建服务器端DatagramSocket,指定端口
        DatagramSocket socket = new DatagramSocket(8800);
        // 2.创建数据报,用于接收客户端发送的数据
        byte[] data = new byte[1024];//创建字节数组,指定接收的数据包的大小
        DatagramPacket packet = new DatagramPacket(data, data.length);

        // 3.接收客户端发送的数据
        System.out.println("****服务器端已经启动,等待客户端发送数据");//输出提示信息
        //通过循环不停的向客户接收数据
        new Thread(()->{
            while(true) {
                try {
                    socket.receive(packet);// 此方法在接收到数据报之前会一直阻塞
                } catch (IOException e) {
                    e.printStackTrace();
                }
                // 4.读取数据
                String info = new String(data, 0, packet.getLength());//创建字符串对象
                System.out.println("我是服务器,客户端说:" + info);//输出提示信息

            }
        }).start();

        final InetAddress[] address = {null};
        final int[] port = {0};
        final boolean[] flag = {false};
        //向客户端发送信息
        new Thread(()->{
        while (true){
            if(!flag[0]){
                // 1.定义客户端的地址、端口号、数据
                address[0] = packet.getAddress();//获取发送端的地址
                port[0] = packet.getPort();//获取 发送端进程所绑定的端口
                flag[0] = true;
            }
            Scanner scanner = new Scanner(System.in);//从键盘接受数据
            String send = scanner.nextLine();//nextLine方式接受字符串
            byte[] data2 = send.getBytes();//将接收到的数据转换为字节数组
            DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address[0], port[0]);// 2.创建数据报,包含响应的数据信息
            try {
                socket.send(packet2); // 3.响应客户端
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        }).start();
    }
}

2.2 UDPClient

package InternetCode.Udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
/*
 * 客户端
 */
public class UDPClient {//公共类
    public static void main(String[] args) throws IOException {//主程序入口
        /*
         * 向服务器端发送数据
         */
        // 1.定义服务器的地址、端口号、数据
        InetAddress address = InetAddress.getByName("localhost");
        int port = 8800;//定义端口类型
        DatagramSocket socket = new DatagramSocket();

        new Thread(()->{
            while(true) {
                //通过循环不同的向客户端发送和接受数据
                Scanner scanner = new Scanner(System.in);//从键盘接受数据
                String send = scanner.nextLine();//nextLine方式接受字符串
                byte[] data = send.getBytes();//将接收到的数据变成字节数组

                //2.创建数据报,包含发送的数据信息
                DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
                // 3.创建DatagramSocket对象
                try {
                    socket.send(packet);// 4.向服务器端发送数据报
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }).start();

        new Thread(()->{
            while (true){
                /*
                 * 接收服务器端响应的数据
                 */
                byte[] data2 = new byte[1024];//创建字节数组
                DatagramPacket packet2 = new DatagramPacket(data2, data2.length);// 1.创建数据报,用于接收服务器端响应的数据
                try {
                    socket.receive(packet2);// 2.接收服务器响应的数据
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //3.读取数据
                String reply = new String(data2, 0, packet2.getLength());//创建字符串对象
                System.out.println("我是客户端,服务器说:" + reply);//输出提示信息
            }
        }).start();

    }
}

运行结果如下:
在这里插入图片描述

借鉴文章:https://blog.csdn.net/qq_41182503/article/details/80179961

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小牧之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值