zoukankan      html  css  js  c++  java
  • 7.3(java学习笔记)网络编程之UDP

    一、UDP

      UDP的全称是User Datagram Protocol(用户数据报协议),是一种无连接的不安全的传输协议,

      传输数据时发送方和接收方无需建立连接,所以是不安全的。

      发送时不建立连接直接发送,发送后不关注接受方能否接到。UDP只负责发出去,后续的事情与之无关。

      1)、使用UDP发送和接受数据的过程:

      1接收数据:

        1.1创建数据包实例,用于接收数据。(指定接收方IP,端口)

        1.2创建接收容器

        1.3将接收容器封装成包

        1.4接收包

        1.5处理包(可以看做拆包,将包中数据拿出来)

        1.6释放资源

      2.发送数据

        2.1创建数据报实例,用于发送数据。(指定发送IP,端口)

        2.2创建发送资源

        2.3将发送资源封装成包(包加上发送目的地,端口)

        2.4发送包

        2.5释放资源

      2)、DatagramSocket & DatagramPacket

        java中将UDP封装成DatagramSocket类,用于发送和接收数据报。

        2.1构造方法:

        DatagramSocket(int port)//创建数据报,并绑定到本地主机的指定端口

        DatagramSocket(int port, InetAddress laddr)//创建数据报,绑定到指定地址的指定端口

        2.2主要方法

        void send(DatagramPacket p)//发送数据包
        void receive(DatagramPacket p)//接收数据包

      

        数据需要打包后才能发送,而接收数据也是以包的形式接收,java中使用DatagramPacket将数据打包。

        构造方法:

        DatagramPacket(byte[] buf, int length)//构造接收数据包及其长度,(设置接收数据包)

        DatagramPacket(byte[] buf, int length, InetAddress address, int port)//构造一个数据包,指定发送主机及端口信息(设置发送数据包)

        主要方法:

        int getLength()//返回要发送的或者要接受的数据长度

        byte[] getData()//获取发生或接受的数据,相当于拆包,获取包内数据。

    Server:(接收数据) 

    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    
    public class Server {
        public static void main(String[] args) throws IOException {
            DatagramSocket server = new DatagramSocket(8888,InetAddress.getByName("localhost"));
            byte[] r = new byte[1024];//接收容器
            DatagramPacket packet = new DatagramPacket(r,r.length);//打包
            server.receive(packet);//接收包
            System.out.println(new String(packet.getData(),0,packet.getLength()));//拆包并解析包
            server.close();        
        }
    }

    Client:(发送数据)   

    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    
    public class Client {
    
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
            DatagramSocket client = new DatagramSocket(8887,InetAddress.getByName("localhost"));
            String msg = "hello udp";
            byte[] b_msg = msg.getBytes();//数据-->字节
         //打包,并加上目的地信息 DatagramPacket packet
    = new DatagramPacket(b_msg,b_msg.length,InetAddress.getByName("localhost"),8888); client.send(packet);//发送包 client.close();//释放资源 } }
    运行结果:
    hello udp

    先运行Server,Server会等待数据,之后运行Client发送数据,Server接收到数据后就会解析。

    想象成寄快递1.东西准备好(准备数据),

          2.转换为固定格式(数据转换为字节)

          3.然后打包,包上贴快递单(邮寄的目的地(IP)和接收人(端口))

          4.然后发送,

          5.接收方接收

          6.然后拆快递(拆包)

          7.然后拿到东西。(字节转换数据)

      

      

    上面的数据是字符串可以直接转换为字节,但如果有时候传输的数据不能直接转换为字节这时该怎么办呢?

    这就要用到IO流的知识,主要使用ByteArrayStream(toByteArray()方法)、DataStream(WriteXxxx()方法)。

    数据-->字节:

    先将数据及其格式通过DataOutputStream写入ByteArrayOutputStream中,再通过ByteArrayOutputStream中的toByteArray()方法将的字节拿出。

    字节-->数据:

    将字节数组放入ByteArrayInputStream中,然后通过DataInputStream中的readXxx读取ByteArrayInputStream中字节数组,将其转换为对应数据类型。

    Server:

    import java.io.ByteArrayInputStream;
    import java.io.DataInputStream;
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    public class Server {
        public static void main(String[] args) throws IOException {
            DatagramSocket server = new DatagramSocket(8888,InetAddress.getByName("localhost"));
            byte[] r = new byte[1024];
            DatagramPacket packet = new DatagramPacket(r,r.length);
            server.receive(packet);
            System.out.println(byteToDouble(packet.getData()));//字节转换为数组
            server.close();        
        }
        
        public static double byteToDouble(byte[] b) throws IOException{
            ByteArrayInputStream bis = new ByteArrayInputStream(b);//将字节放入ByteArratInputStream中
            DataInputStream dis = new DataInputStream(bis);//通过dis读取bis中字节
            double data = dis.readDouble();//通过dis.readXxxx读取bis中的字节数组。
            return data;
        }
    }

    Client:

    import java.io.ByteArrayOutputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    public class Client {
    
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
            DatagramSocket client = new DatagramSocket(8887,InetAddress.getByName("localhost"));
        //    String msg = "hello udp";
            Double data = 9.1;
            byte[] b_data = doubleToByte(data);//数据转换为字节
            DatagramPacket packet = new DatagramPacket(b_data,b_data.length,InetAddress.getByName("localhost"),8888);
            client.send(packet);
            client.close();
        }
        
        public static byte[] doubleToByte(double dou) throws IOException{
            ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建字节数组输入流
            DataOutputStream dos = new DataOutputStream(bos);//通过dos想bos中写入
            dos.writeDouble(dou);//通过dos中的write.Xxxx将dou写入bos中
            dos.flush();
            dos.close();
            byte[] data = bos.toByteArray();//将bos中字节取出。
            return data;
        }
    }
    运行结果:
    9.1
  • 相关阅读:
    Spring_AOP动态代理详解(转)
    Java中spring读取配置文件的几种方法
    SpringMVC工作原理2(代码详解)
    SpringMVC工作原理1(基础机制)
    Web服务器和应用服务器简介
    WEB服务器与应用服务器解疑
    WebService基本概念及原理
    HTTP协议
    TCP、UDP协议间的区别(转)
    HTTP、TCP、UDP以及SOCKET之间的区别/联系
  • 原文地址:https://www.cnblogs.com/huang-changfan/p/9926558.html
Copyright © 2011-2022 走看看