当前位置:   article > 正文

UDP的网络编程_udp协议编程

udp协议编程

UDP的网络编程

一 :UDP的基本概念

​ UDP协议的全称是用户数据报,在网络中它与TCP协议一样用于处理数据包。在OSI模型中,在第四层——传输层,处于IP协议的上一层。UDP有不提供数据报分组、组装和不能对数据包的排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。

二:使用UDP的原因

​ 它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包, 也不会对接收结果产生太大影响。比如我们聊天用的ICQ和OICQ就是使用的UDP协议。在选择使用协议的时候,选择UDP必须要谨慎。在网络质量令人不 十分满意的环境下,UDP协议数据包丢失会比较严重。

三:JAVA中UDP的API类

  1. InetAddress: 用于描述和包装一个Internet IP地址。
方法名返回值
getLocalhost()返回封装本地地址的实例
getAllByName(String host)返回封装Host地址的InetAddress实例数组
getByName(String host)返回一个封装Host地址的实例。其中,Host可以是域名或者是一个合法的IP地址。
InetAddress.getByAddress(addr)根据地址串返回InetAddress实例
  1. DatagramSocket: 用于接收和发送UDP的Socket实例。
方法名返回值
DatagramSocket()通常用于客户端编程,它并没有特定监听的端口,仅仅使用一个临时的。程序会让操作系统分配一个可用的端口
DatagramSocket(int port)创建实例,并固定监听Port端口的报文。通常用于服务端
DatagramSocket(int port, InetAddress localAddr)这是个非常有用的构建器,当一台机器拥有多于一个IP地址的时候,由它创建的实例仅仅接收来自LocalAddr的报文。
receive(DatagramPacket d)接收数据报文到d中。receive方法产生一个“阻塞”。“阻塞”是一个专业名词,它会产生一个内部循环,使程序暂停在这个地方,直到一个条件触发。
send(DatagramPacket dp)发送报文dp到目的地
setSoTimeout(int timeout)设置超时时间,单位为毫秒。
close()应用程序退出的时候,通常会主动释放资源,关闭Socket,但是由于异常地退出可能造成资源无法回收。所以,应该在程序完成时,主动使用此方法关闭Socket,或在捕获到异常抛出后关闭Socket。
  1. DatagramPacket:用于处理报文,它将Byte数组、目标地址、目标端口等数据包装成报文或者将报文拆卸成Byte数组。
方法名返回值
DatagramPacket(byte[] buf, int length)将数据包中Length长的数据装进Buf数组,一般用来接收客户端发送的数据
DatagramPacket(byte[] buf, int offset, int length)将数据包中从Offset开始、Length长的数据装进Buf数组
DatagramPacket(byte[] buf, int length, InetAddress clientAddress, int clientPort)从Buf数组中,取出Length长的数据创建数据包对象,目标是clientAddress地址,clientPort端口, 通常用来发送数据给客户端。
DatagramPacket(byte[] buf, int offset, int length, InetAddress clientAddress, int clientPort)从Buf数组中,取出Offset开始的、Length长的数据创建数据包对象,目标是clientAddress地 址,clientPort端口,通常用来发送数据给客户端。
getData()从实例中取得报文的Byte数组编码。
setDate(byte[] buf)将byte数组放入要发送的报文中。

四:java中UDP的网络编程示例

  1. 基础版本
//UDP服务端
public class BaseUdpServer {

    public static void main(String[] args) throws IOException {
        System.out.println("基础版UDP服务器启动....");
        //定义UDP服务端socket
        DatagramSocket datagramSocket = new DatagramSocket(8888);
        //接受客户端传递过来的容器
        byte[] contain = new byte[1024];
        //解包过程
        DatagramPacket datagramPacket = new DatagramPacket(contain,contain.length);
        //等待接受消息阻塞
        datagramSocket.receive(datagramPacket);
        //打印消息
        System.out.println(new String(contain,0,datagramPacket.getLength()));

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

//UDP的客户端
public class BaseUdpClient {

    public static void main(String[] args) throws IOException {
        System.out.println("基础版UDP客户端启动....");
        //定义UDP客户端socket
        DatagramSocket datagramSocket = new DatagramSocket(6666);
        //定义发送的消息
        String msg = "hello UDP";
        //装包过程(注意:需要指定服务器端的IP和端口号)
        DatagramPacket datagramPacket = new DatagramPacket(msg.getBytes(),
                msg.getBytes().length,
                InetAddress.getByName("localhost"),
                8888);
        //发送消息
        System.out.println("消息发送中,发送的消息为: msg = " + msg);
        datagramSocket.send(datagramPacket);

        //关闭连接
        datagramSocket.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

执行结果为:

在这里插入图片描述

在这里插入图片描述

2) 发送基本类型数据

//客户端
public class BaseUdpTypeClient {

    public static void main(String[] args) throws IOException {
        System.out.println("基本类型UDP客户端启动....");
        //定义UDP服务端socket
        DatagramSocket datagramSocket = new DatagramSocket(6666);

        //首先思路,要将基本类型转化成字节数据,需要用到两个IO流
        //字节数组输出流
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        //数据输出流
        DataOutputStream dataOutputStream = new DataOutputStream(
                new BufferedOutputStream(byteArrayOutputStream));
        //输出字符类型
        dataOutputStream.writeUTF("UTF-8");
        //输出数字类型
        dataOutputStream.writeInt(12);
        //输出double类型
        dataOutputStream.writeDouble(12.00);
        //输出boolean类型
        dataOutputStream.writeBoolean(true);
        //数据的刷新
        dataOutputStream.flush();

        //解包过程
        DatagramPacket datagramPacket = new DatagramPacket(byteArrayOutputStream.toByteArray(),0,
                byteArrayOutputStream.toByteArray().length,
                InetAddress.getByName("localhost"),
                8888);
        //发送消息
        System.out.println("消息发送中,发送的消息为: msg = \"UTF-8\"");
        System.out.println("消息发送中,发送的消息为: msg = 12");
        System.out.println("消息发送中,发送的消息为: msg = 12.00");
        System.out.println("消息发送中,发送的消息为: msg = true");
        datagramSocket.send(datagramPacket);

        //关闭连接
        dataOutputStream.close();
        byteArrayOutputStream.close();
        datagramSocket.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
//服务端
public class BaseUdpTypeServer {
    public static void main(String[] args) throws IOException {
        System.out.println("基础类型UDP服务器启动....");
        //定义UDP服务端socket
        DatagramSocket datagramSocket = new DatagramSocket(8888);
        //接受客户端传递过来的容器
        byte[] contain = new byte[1024];
        //解包过程
        DatagramPacket datagramPacket = new DatagramPacket(contain,contain.length);
        //阻塞消息
        datagramSocket.receive(datagramPacket);
        //获取字节数据
        byte[] data = datagramPacket.getData();
        //获取字节数据长度
        int length = datagramPacket.getLength();
        //获取数据流
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data,0,length);

        DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(byteArrayInputStream));
        System.out.println(dataInputStream.readUTF());
        System.out.println(dataInputStream.readInt());
        System.out.println(dataInputStream.readDouble());
        System.out.println(dataInputStream.readBoolean());

        //关闭
        datagramSocket.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

执行结果:

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

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

闽ICP备14008679号