安卓接收UDP广播的例子

1,859 阅读3分钟

「这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战

安卓接收UDP广播的例子

我们在互联网产品公司呆习惯了,给我们一个地址一个端口,我们就拿来直接连接就行了。在同一个局域网下,我们不知道对方的IP,是怎么连接对方的呢,像我们以前在网吧玩的单机局域网游戏,为什么一进入游戏,就可以联机玩了呢?IP地址是经常变动的,它为什么不需要我们手动输入IP了呢。带着这些疑问,接着看该文章。

UDP广播是什么

广播顾名思义,是指由一台主机向局域网的其它机器发送消息的过程。 因为是无连接的,并且一对多发送消息,所以概念中广播只能使用UDP的方式。

在主机端:通过某个端口不断的发送广播内容,内容包含IP地址和端口。
在客户端: 通过某个端口监听广播内容,解析广播内容,去除ip地址和端口,然后使用TCP连接。

在UDP广播中,又分为两种模式

  • 定向广播,又叫直接广播,向某台在网络中的设备发送数据,这种广播会经过路由器到达指定的位置。
  • 有限广播,广播使用广播地址255.255.255.255,将消息发送到在同一广播网络上的每个主机,不会经过路由器

看看百科的解释

有限广播地址也称为本地广播地址,TCP/IP协议规定32位全为1的IP地址(255.255.255.255)用于本网广播。 在主机不知道本机所处的网络时(如主机的启动过程中),只能采用有限广播方式,通常由无盘工作站启动时使用,希望从网络IP地址服务器处获得一个IP地址。

广播地址包含一个有效的网络号和主机号,技术上就称为直接广播地址。

有限广播的数据包里不包含自己的ip地址,而直接广播地址里包含自身的ip地址。

发送广播

我用JAVA去实现发送广播的过程,创建数据包传输对象DatagramSocket 绑定端口.

public static void udpSend() {
		new Thread(new Runnable() {
			public void run() {

				while (true) {
					try {
						Thread.sleep(5000);
						try {
							// byte[] bytes = new byte[0]; //我不需要传递数据到服务器,所以写了个空的
							byte[] bytes = "type_name".getBytes();
							InetAddress inet = InetAddress.getByName("255.255.255.255");
							DatagramPacket packet = new DatagramPacket(bytes, bytes.length, inet, 1234);
							DatagramSocket datagramSocket = new DatagramSocket();
							datagramSocket.setSoTimeout(10000);

							System.out.println("send");
							datagramSocket.send(packet);

						} catch (UnknownHostException e) {
							e.printStackTrace();
						} catch (SocketException e) {
							e.printStackTrace();
						} catch (IOException e) {
							e.printStackTrace();
						}
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}

		}).start();
	}

接收广播

用循环阻塞接收发送过来的广播。
一般情况下,获取到主机地址后,再进行TCP连接。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true)
                    udpReceiver();
            }
        }).start();

    }

    public static void udpReceiver() {
        try {
            DatagramSocket datagramSocket = new DatagramSocket(1234);
            byte[] buff = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buff, buff.length);
            datagramSocket.receive(packet);
            InetAddress ip = packet.getAddress();
            String ipStr = ip + "";

            String ip_new = ipStr.substring(1, ipStr.length());
            System.out.println("ip_new:" + ip_new);
            Log.d("====", "udpReceiver:" + ip_new);

            // 获取内容: 约定好的词。 收到约定好的词之后,不再进行 while(true)
            String text = new String(packet.getData(),0, packet.getLength());
            Log.d("====", "text:" + text);

            datagramSocket.close();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}