当前位置:   article > 正文

java网络编程(四)----通信协议之UDP_java网络编程 第4关:简单的udp通信

java网络编程 第4关:简单的udp通信

前言

在了解了TCP协议中java代码TCP协议中java代码的相关编写后,今天我们继续了解UDP协议

1.UDP: 发短信

[1] 不连接,不稳定
[2] 客户端与服务端没有明确界限
[3] 不管有没有准备好,都可以发送给你
(就好比导弹攻击;DDOS,洪水攻击)

1.1 我们下面先来模拟一个单方面的接收和单方面发送的例子
发送端

package com.gs.lesson03;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

//不需要连接服务器
public class UdpClientDemo01 {
    public static void main(String[] args) throws Exception {
        // 1.建立一个Socket
        DatagramSocket socket = new DatagramSocket();
        // 2.建个包
        String msg = "你好啊,服务器!";
        //2.1发送给谁(IP地址+端口号)
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 9090;
        //数据 数据的起始位置 数据的结束位置 IP地址 端口号
        DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
        //3. 发送包
        socket.send(packet);
        //4.关闭流
        socket.close();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

接收端

package gs.lesson03;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

//还是要等待客户端连接
public class UdpServerDemo01 {
    public static void main(String[] args) throws Exception {
        //1.开放端口
        DatagramSocket socket = new DatagramSocket(9090);
        //2.接收数据包
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);

        //阻塞(就是等待接收)
        socket.receive(packet);
        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(new String(packet.getData(),0,packet.getLength()));
        //3.关闭连接
        socket.close();

    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

1.2 上面的例子显然只是一个入门,因为他只能接收一条信息;那么我们如何实现接收多条信息,并在适当的时候断开连接呢?
下面我们模拟一个接收方可以接收多条信息,并在接收到bye这个命令后就断开连接。

发送方

package gs.chat;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class UdpSenderDemo01 {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(8888);

        //准备数据,控制台取 System.in
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        while(true){
            String data = reader.readLine();
            byte[] datas = data.getBytes();
            DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",6666));
            //发送数据包
            socket.send(packet);
            //当接收到 bye时退出
            if(data.startsWith("bye")){
                break;
            }

        }


        socket.close();

    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

接收方

package gs.chat;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdpReceiverDemo01 {

    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(6666);

        while (true){
            // 准备接收包裹
            byte[] container = new byte[1024];
            DatagramPacket packet = new DatagramPacket(container,0,container.length);
            // 阻塞式接收包裹
            socket.receive(packet);

            // 当收到 bye时断开连接
            byte[] data = packet.getData();
            String receiveData = new String(data,0,data.length);
            System.out.println(receiveData);
            if(receiveData.startsWith("bye")){
                break;
            }

        }

        socket.close();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

1.3 上面的例子还是显然不足的,我们还是没有实现真正的通信,也就是你说一句,我能回一句的那种。那我们该如何实现呢?
这里我们可以开启两个线程进行模拟,这两个线程分别代表接收方和发送方。也就是每个人都是接受信息的人,也是发送信息的人。
[1] 编写接受方线程

package gs.chat;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class TalkReceiver implements Runnable {

    DatagramSocket socket = null;
    //接收方的端口
    private int port;
    //信息来自谁
    private String msgFrom;

    public TalkReceiver(int port,String msgFrom) {
        this.port = port;
        this.msgFrom = msgFrom;
        try {
            //新建数据报连接
            socket = new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {


        while (true){
            try {
                // 准备接收包裹
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container,0,container.length);
                // 阻塞式接收包裹
                socket.receive(packet);

                // 当收到 bye时断开连接
                byte[] data = packet.getData();
                String receiveData = new String(data,0,data.length);
                System.out.println(msgFrom+":"+receiveData);
                if(receiveData.startsWith("bye")){
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        socket.close();
    }
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

[2] 编写发送方的线程

package gs.chat;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;

public class TalkSend implements Runnable {
    DatagramSocket socket = null;
    BufferedReader reader = null;

    //发送者的端口
    private int fromPort;
    //接收者的IP
    private String toIp;
    //接收者的端口
    private int toPort;

    public TalkSend(int fromPort, String toIp, int toPort) {
        this.fromPort = fromPort;
        this.toIp = toIp;
        this.toPort = toPort;

        try {
            //新建一个数据报连接
            socket = new DatagramSocket(fromPort);
            //获取我们键盘上的输入
            reader = new BufferedReader(new InputStreamReader(System.in));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {

        while(true){

            try {
                //读取相应的数据形成数据源包
                String data = reader.readLine();
                byte[] datas = data.getBytes();
                DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress(this.toIp,this.toPort));
                //发送数据包
                socket.send(packet);
                //当接收到 bye时退出
                if(data.startsWith("bye")){
                    break;
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        socket.close();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

[3] 模拟通信的双方,一个为Teacher,需要开启一个接收线程和发送线程
假设老师要发送给学生的地址是localhost 8888,则学生接收的地址就是localhost 8888
学生要发送给老师的地址是localhost 9999, 则老师接收的地址就是localhost 9999。
(看起来描述很愚蠢,只要你不被代码绕进去就好)

package gs.chat;

public class TalkTeacher {
    public static void main(String[] args) {
        new Thread(new TalkSend(5555,"localhost",8888)).start();
        new Thread(new TalkReceiver(9999,"student")).start();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

[4] 一个为Student

package gs.chat;

public class TalkStudent {
    public static void main(String[] args) {
        //开启两个线程
        new Thread(new TalkSend(7777,"localhost",9999)).start();
        new Thread(new TalkReceiver(8888,"teacher")).start();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

运行后就是一个mini的聊天室了
在这里插入图片描述
在这里插入图片描述

总结

以上这些网络编程的学习笔记都是在B站看狂神时所写的。如果有任何疑惑,可以下方留言,也请多关注这个UP主。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/425985
推荐阅读
相关标签
  

闽ICP备14008679号