UDP网络通信

UDP通信跟TCP通信的最大区别在于 他不用创建连接 

就像打电话和发短信的区别。

不可靠、无连接、面向报文

 面向数据报文导致的一个后果:
由于底层(物理层+网络层))都对一次发送的数据有大小限制。如果强行发送大于限制的数据,就会出现数据被截断。
全双工:同一个信道是双向的。

UDP协议的最适用场景
对实时性要求较高,对可靠性要求较低的场景
实时聊天(语音、视频聊天)
UDP支持广播。如果有广播需求,也可以考虑用UDP。

下面用模拟一下udp场景

接收端

public class ChatServer {
    public static void main(String[] args) throws Exception {
        //开放端口
        DatagramSocket socket = new DatagramSocket(9998);
        //定义bytes去开辟空间接收数据
        byte[] bytes = new byte[9];
        //接收数据包
        DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length);
        //阻塞进程 等待接收
        socket.receive(packet);
        for (byte aByte : bytes) {
            System.out.println("接收完了"+aByte);
        }
        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(new String(packet.getData(),0,packet.getLength()));
    }
}

发送端

public class ChatUser {
    public static void main(String[] args) throws Exception {
        //建立一个数据包连接
        DatagramSocket socket = new DatagramSocket(9997);
        //创建一个数据包
        String msg = "李佳琪";
        byte[] msgByteArray = msg.getBytes();
        InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
        //参数解释  数据包 数据的起始位置 ip 端口
        DatagramPacket datagramPacket = new DatagramPacket(msgByteArray,0,msgByteArray.length,inetAddress,9998);
        //发送数据包
        socket.send(datagramPacket);
        //关闭连接
        socket.close();
    }
}

循环发送和接收

循环发送

public class ChatTwo {
    public static void main(String[] args) throws Exception {
        //创建自己的服务
        DatagramSocket datagramSocket = new DatagramSocket(8888);
        while (true){
            //控制写入数据
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String data = reader.readLine();
            //转换为字节数组
            byte[] bytes = data.getBytes();
            //创建数据包
            DatagramPacket datagramPacket = new DatagramPacket(bytes,0,bytes.length, InetAddress.getByName("localhost"),666);
            //发送数据包
            datagramSocket.send(datagramPacket);
            if ("bye".equals(data)){
                System.out.println("退出聊天");
                break;
            }
        }
        datagramSocket.close();

    }
}

循环接收

public class ChatOne {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(666);
        while(true){
            //接收包裹
            byte[] bytes = new byte[1024];
            //开启数据包空间
            DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length);
            //接收数据包
            socket.receive(packet);
            //获取数据并转换为string
            byte[] data= packet.getData();
            String receiveData = new String(data,0,packet.getLength());
            //输出内容
            System.out.println(receiveData);
            if ("bye".equals(receiveData)){
                System.out.println("退出聊天");
                break;
            }
        }
    }
}

下面实现正常的聊天功能

发送消息线程类

/**
 * @author : LeeGaki
 * @date : 2022/6/5 19:47
 * 面向面试编程 --> 李佳琪
 */
public class ChatSend implements Runnable{
    /**
     * 创建自己的连接
     * 从控制台接收
     * 自己的端口
     * 发到的ip和端口
     */
    DatagramSocket datagramSocket = null;
    BufferedReader bufferedReader = null;
    private int fromPort;
    private String toIp;
    private int toPort;
    private String myName;
    private String toName;
    /**
     * 构造方法
     * 创建从控制台接收
     * @param fromPort
     * @param toIp
     * @param toPort
     */
    public ChatSend(int fromPort, String toIp, int toPort,String myName,String toName) {
        this.fromPort = fromPort;
        this.toIp = toIp;
        this.toPort = toPort;
        this.myName = myName;
        this.toName = toName;
        try {
            bufferedReader = new BufferedReader(new InputStreamReader(System.in));
            datagramSocket = new DatagramSocket(fromPort);
     } catch (SocketException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void run() {
        try {
            System.out.println("您的身份是"+this.myName);
            System.out.println("直接写入即可发送消息给"+toName);
            while(true){
                //发送控制台写入的数据
                String data = bufferedReader.readLine();
                byte [] bytes = data.getBytes();
                DatagramPacket datagramPacket = new DatagramPacket(bytes,0,bytes.length, new InetSocketAddress(this.toIp,this.toPort));
                datagramSocket.send(datagramPacket);
                if ("bye".equals(data)){
                    break;
                }
            }
            datagramSocket.close();
            bufferedReader.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

接收消息线程类

/**
 * @author : LeeGaki
 * @date : 2022/6/5 20:12
 * 面向面试编程 --> 李佳琪
 */
public class ChatReceive implements Runnable{
    DatagramSocket datagramSocket = null;
    private String fromUser;
    private int myPort;
    public ChatReceive(String fromUser,int myPort){
        this.fromUser = fromUser;
        this.myPort = myPort;
        try {
            datagramSocket = new DatagramSocket(myPort);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }
    public String getFromUser(){
        return this.fromUser;
    }
    @Override
    public void run() {
        while (true){
            byte [] bytes = new byte[1024];
            DatagramPacket datagramPacket = new DatagramPacket(bytes,0,bytes.length);
            try {
                datagramSocket.receive(datagramPacket);
                byte[] data = datagramPacket.getData();
                String str = new String(data,0,datagramPacket.getLength());
                System.out.println(this.fromUser+":"+str);
                if ("bye".equals(str)){
                    System.out.println("回复bye确认拜拜");
                    break;
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        datagramSocket.close();

    }
}

实现类

/**
 * @author : LeeGaki
 * @date : 2022/6/5 20:25
 * 面向面试编程 --> 李佳琪
 */
public class ChatStudent {
    public static void main(String[] args) {
        ChatReceive receiveUser = new ChatReceive("李佳琪", 7777);
        ChatSend sendUser = new ChatSend(7776, "127.0.0.1", 7775, "郭佳帅", receiveUser.getFromUser());
        new Thread(receiveUser).start();
        new Thread(sendUser).start();
    }
}
/**
 * @author : LeeGaki
 * @date : 2022/6/5 20:27
 * 面向面试编程 --> 李佳琪
 */
public class ChatTeacher {
    public static void main(String[] args) {
        ChatReceive receiveUser = new ChatReceive("郭佳帅", 7775);
        ChatSend sendUser = new ChatSend(7774, "127.0.0.1", 7777, "李佳琪", receiveUser.getFromUser());
        new Thread(receiveUser).start();
        new Thread(sendUser).start();
    }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

LeeGaKi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值