前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >网络通信学习笔记(四)---UDP通信

网络通信学习笔记(四)---UDP通信

作者头像
萌萌哒的瓤瓤
发布2021-01-13 17:40:49
6250
发布2021-01-13 17:40:49
举报
文章被收录于专栏:java,python,数据结构,算法

1. UDP协议

这里我们首先需要明白一点,UDP本身就是一种不需要连的协议,所以是不存在客户端与服务端的.

我们通常是通过发送方与接收方的概念来区分,但是我们又需要明白一点发送方与接收方可能是同一个机器.

1.1 UDP消息发送1.0

这里我们还是通过代码来讲解,并且这里我们还是分两个部分来讲.

一是发送方,另一个就是接收方

发送方:

代码语言:javascript
复制
  public static void main(String[] args) throws Exception {
        //建立一个DatagramSocket对象,这里同时我们也开放他的6666端口号,只要开放端口号之后就不存在是发送方还是接收方的概念了,既可以是发送方,也可以是接收方.
        DatagramSocket socket=new DatagramSocket(6666);
        //发送的信息
        String msg="你好啊,服务器!";
        //发送的对象的ip地址以及端口号
        InetAddress localhost=InetAddress.getByName("localhost");
        int port=9999;
        //发送的数据报的各类信息,数据的起始位置,接收方的ip及端口号
        DatagramPacket packet=new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port);
        //发送数据报
        socket.send(packet);
    }

接收方:

代码语言:javascript
复制
public static void main(String[] args) throws Exception{
        //开放端口
        DatagramSocket socket=new DatagramSocket(9999);
        //接收数据报
        byte[]buffer=new byte[1024];
        DatagramPacket packet=new DatagramPacket(buffer,0,buffer.length);
        //阻塞接受将信息存入到packet对象之中
        socket.receive(packet);
        //打印数据
        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(new String(packet.getData(),0,packet.getLength()));
        //关闭连接
        socket.close();

    }

其实从上面我们也能够看出来UDP就是不需要连接的,因为整个的过程中我们都没有看到ServerSocket这个对象,而是通过 DatagramSocket 这个对象来进行.

其次就是之前我们都是通过 流的形式 来进行数据的传输,但是在UDP中我们则是通过 数据报 的形式来进行,这里其实如果大家学过计算机网络这门课程的话,应该就懂了.

实际效果:

在这里插入图片描述
在这里插入图片描述

1.2 UDP消息发送2.0

上面的是我们只能在程序中规定好消息,然后发送,并且整个过程是一次性的,程序执行完就没有了,现在我们编写的就是能够通过键盘输入并且传递信息,并且接收能够持续接受信息,只有当接收到bye这样一个关键字时,我们才退出整个程序.

发送方:

代码语言:javascript
复制
public static void main(String[] args) throws Exception {
        DatagramSocket socket=new DatagramSocket(9999);
        while (true){
            BufferedReader Reader=new BufferedReader(new InputStreamReader(System.in));
            String data= Reader.readLine();
            byte [] bytes=data.getBytes();
            DatagramPacket packet=new DatagramPacket(bytes,0,bytes.length,new InetSocketAddress("localhost",8888));
            socket.send(packet);
            if(data.equals("bye"))
                break;
        }
        socket.close();
    }

接收方:

代码语言:javascript
复制
 public static void main(String[] args) throws Exception {
        DatagramSocket socket=new DatagramSocket(8888);
        while (true){
            byte[] bytes=new byte[1024];
            DatagramPacket packet=new DatagramPacket(bytes,0,bytes.length);//阻塞式接收包裹
            socket.receive(packet);
            byte[]newdata=packet.getData();
            String data=new String(newdata,0,newdata.length);
            System.out.println(data);
            if(data.equals("bye"))
                break;
        }
        socket.close();
    }

实际效果:

在这里插入图片描述
在这里插入图片描述

1.3 UDP多线程聊天

这里我们会运用到多线程的理念,如果有不了解的建议先去了解一下之后再来学习.

这里我们主要为发送方与接收方两个角色各创建一个线程

TalkSend

代码语言:javascript
复制
public class TalkSend implements Runnable {
    DatagramSocket socket=null;
    BufferedReader Reader=null;
    private String toip;
    private int fromport;
    private int toport;

    public TalkSend(String toip, int fromport, int toport) throws Exception {
        this.toip = toip;
        this.fromport = fromport;
        this.toport = toport;
        socket=new DatagramSocket(fromport);
        Reader=new BufferedReader(new InputStreamReader(System.in));
    }
    @Override
    public void run() {
        while (true){
            try {
                String data= Reader.readLine();
                byte [] bytes=data.getBytes();
                DatagramPacket packet=new DatagramPacket(bytes,0,bytes.length,new InetSocketAddress(this.toip,this.toport));
                socket.send(packet);
                if(data.equals("bye"))
                    break;
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        socket.close();
    }
}

TalkReceive

代码语言:javascript
复制
public class TalkReceive implements Runnable {
    DatagramSocket socket=null;
    private String msgfrom;
    private int port;
    public TalkReceive(String msgfrom,int port) throws SocketException {
        this.msgfrom=msgfrom;
        this.port = port;
        socket=new DatagramSocket(port);
    }
    @Override
    public void run() {
        while (true){
            try {
                byte[] bytes=new byte[1024];
                DatagramPacket packet=new DatagramPacket(bytes,0,bytes.length);
                socket.receive(packet);
                byte[]newdata=packet.getData();
                String data=new String(newdata,0,newdata.length);
                System.out.println(msgfrom+":"+data);
                if(data.equals("bye"))
                    break;
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        socket.close();
    }
}

创建完发送与接收线程之后,我们就可以创建学生与老师两个用户来实现这个聊天程序.

学生:

代码语言:javascript
复制
public class TalkStudent {
    public static void main(String[] args) throws Exception {
        new Thread(new TalkSend("localhost",7777,9999)).start();
        new Thread(new TalkReceive("老师",8888)).start();
    }
}

教师:

代码语言:javascript
复制
public class TalkTeacher {
    public static void main(String[] args) throws Exception {
        new Thread(new TalkSend("localhost",5555,8888)).start();
        new Thread(new TalkReceive("学生",9999)).start();
    }
}

这里我们只需要稍微注意一下端口号的对应就行了

实际效果:

在这里插入图片描述
在这里插入图片描述

这里出现中文乱码主要是因为cmd是通过GBK来进行编码的,这里可以自己去设置成UTF-8的编码方式.

都看到这儿了,如果觉得对你有帮助的话,可以关注我的公众号,坚持日更技术好文章.

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/09/17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. UDP协议
    • 1.1 UDP消息发送1.0
      • 1.2 UDP消息发送2.0
        • 1.3 UDP多线程聊天
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档