Android收发UDP报文详解

扣扣技术交流群:460189483

参考链接如下,写的非常非常好,我只是把他们写的优秀的搬过来做笔记,防止以后忘记,本博客所有内容均经过代码验证

https://blog.csdn.net/ITermeng/article/details/73482669?locationNum=9&fps=1

https://blog.csdn.net/weixin_37716758/article/details/81359092

1. 安卓UDP发送步骤

1. 构造DatagramSocket对象
2. 根据发送IP 来创建InetAddress对象
3. 根据InetAddress对象、发送端口号、发送数据 来创建发送的DatagramPacket数据包对象
4. 调用DatagramSocket对象的send(datagramPacket) 方法,发送UDP报文
5. 调用DatagramSocket对象的close() 关闭套接字连接

2. 安卓UDP接收步骤

1. 需要根据接收端口号 构造DatagramSocket对象

2. 创建发送的DatagramPacket数据包对象

3. 调用DatagramSocket对象的receive(datagramPacket) 方法,接收UDP报文

 

一 . 基础知识解释

首先学习了解一下UDP、TCP是什么东西,基础知识的链接如下,非常全了,不再赘述

https://blog.csdn.net/itermeng/article/details/72970099 

通过上面的UDP发送、接收步骤可以看出来,DatagramSocket、InetAddress、DatagramPacket这3个对象很关键,下面给出三个对象的构造函数及方法,补充一下基础,如下:

1.1 DatagramSocket学习

(1)定义概念

此类表示用来发送和接收数据报包的套接字。

数据报套接字是包投递服务的发送或接收点。每个在数据报套接字上发送或接收的包都是单独编址和路由的。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。

在 DatagramSocket 上总是启用 UDP 广播发送。为了接收广播包,应该将 DatagramSocket 绑定到通配符地址。在某些实现中,将 DatagramSocket 绑定到一个更加具体的地址时广播包也可以被接收。

(2)构造函数总结

构造函数名称含义
DatagramSocket()构造数据报套接字并将其绑定到本地主机上任何可用的端口。
DatagramSocket(int port)创建数据报套接字并将其绑定到本地主机上的指定端口。
DatagramSocket(int port, InetAddress laddr)创建数据报套接字,将其绑定到指定的本地地址。


(3)重要方法摘要

方法名称含义
void close()关闭此数据报套接字。
void connect(InetAddress address, int port)将套接字连接到此套接字的远程地址
boolean isClosed()返回是否关闭了套接字。
void receive(DatagramPacket p)从此套接字接收数据报包。
void send(DatagramPacket p)从此套接字发送数据报包。
DatagramSocket(int port, InetAddress laddr)

创建数据报套接字,将其绑定到指定的本地地址。

1.2 InetAddress学习

(1) 定义概念

此类表示互联网协议 (IP) 地址。

IP 地址是 IP 使用的 32 位或 128 位无符号数字,它是一种低级协议,UDP 和 TCP 协议都是在它的基础上构建的。InetAddress 的实例包含 IP 地址,还可能包含相应的主机名(取决于它是否用主机名构造或者是否已执行反向主机名解析)。

(2)创建方法
注意,创建此类事通过类方法而获取,并非构造方法。

方法名称含义
static InetAddress getByAddress(byte[] addr)在给定原始 IP 地址的情况下,返回 InetAddress 对象。
static InetAddress getByAddress(String host, byte[] addr)根据提供的主机名和 IP 地址创建 InetAddress。
static InetAddress getByName(String host)在给定主机名的情况下确定主机的 IP 地址。

表示数据报包。

1.3 DatagramPacket学习

(1)定义概念

此类表示数据包。

数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证。

(2)构造方法

构造函数名称含义
DatagramPacket(byte[] buf, int length)用来接收长度为 length 的数据包
DatagramPacket(byte[] buf, int length, InetAddress address, int port)构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号

 

 

 

 

二. 发送、接收UDP报文步骤讲解


在此程序中,将UDP报文的发送、接收操作分别写入到两个线程中,根据具体需求进行调用。

2.1. 数据报发送 解析

以下步骤都在发送线程内,需要注意的是发送UDP报文逻辑单一,顺序执行完毕线程即可结束,不涉及到后台等待的需求,所以执行完后即可关闭套接字连接。

发送步骤

  1. 构造DatagramSocket对象
  2. 根据发送IP 来创建InetAddress对象
  3. 根据InetAddress对象、发送端口号、发送数据 来创建发送的DatagramPacket数据包对象
  4. 调用DatagramSocket对象的send(datagramPacket) 方法,发送UDP报文
  5. 调用DatagramSocket对象的close() 关闭套接字连接

对应以上步骤,代码展示(仅为部分重要代码):

    Byte[] buf="hello android! ".getBytes();
    DatagramSocket sendSocket = new DatagramSocket();
    InetAddress serverAddr = InetAddress.getByName(SEND_IP);
    DatagramPacket outPacket = new DatagramPacket(buf, buf.length,serverAddr, SEND_PORT);
    sendSocket.send(outPacket);
    sendSocket.close();

2.2 数据报接收 解析

以下步骤都在接收线程内,同发送线程大致相同,但需要注意这两者本质的区别:发送线程里的逻辑执行一遍即可结束,但是接收线程需要在后台待定等待接收UDP报文,不可执行一遍就结束!相当于在一个界面中,可多次创建发送线程用来发送报文,但是接收线程只需在界面初始化时创建,从而一直监听报文接收(若重新进入界面,逻辑如上)。

所以,在接收线程内部需要用到循环,在循环内部调用套接字对象的receive() 方法来接收UDP报文。注意套接字对象的连接关闭,发送线程中单一的逻辑,执行完发送过程即可关闭连接,但是在接收线程中使用了循环,所以需要用一个全局标识量来控制循环,若界面退出或销毁则将标示值置为false,这样接收线程即可结束,再关闭套接字连接。

接收步骤

  1. 需要根据接收端口号 构造DatagramSocket对象
  2. 创建发送的DatagramPacket数据包对象
  3. 调用DatagramSocket对象的receive(datagramPacket) 方法,接收UDP报文

对应以上步骤,代码展示(仅为部分重要代码):

    DatagramSocket receiveSocket = new DatagramSocket(RECEIVE_PORT);

    while(listenStatus){
         byte[] inBuf= new byte[1024];
         DatagramPacket inPacket=new DatagramPacket(inBuf,inBuf.length);
         receiveSocket.receive(inPacket);                                           
         if(!inPacket.getAddress().equals(serverAddr)){
             throw new IOException("未知名的报文");
          }

         receiveInfo = inPacket.getData();
         receiveHandler.sendEmptyMessage(1);
     }

 

 

 

 

 

 

 


 

 

 

 

 

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值