UDP 广播知识研究


Android 客户端 代码
package com.example.udp;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "AppCompatActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.i(TAG, getLocalHostIp());
        // TODO Auto-generated method stub
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                int port = 9999;// 开启监听的端口
                DatagramSocket ds = null;
                DatagramPacket dp = null;
                byte[] buf = new byte[1024];// 存储发来的消息
                try {
                    // 绑定端口的
                    ds = new DatagramSocket(port);
                    dp = new DatagramPacket(buf, buf.length);
                    Log.i(TAG,"监听广播端口打开:");
                    while (true) {
                        ds.receive(dp);
                        int i;
                        StringBuffer sbuf = new StringBuffer();
                        for (i = 0; i < 1024; i++) {
                            if (buf[i] == 0) {
                                break;
                            }
                            sbuf.append((char) buf[i]);
                        }
                        Log.i(TAG,"收到广播消息:" + sbuf.toString());
                        System.out.println("收到广播消息:" + sbuf.toString());
                        try {
                            Thread.sleep(1000);
                        }
                        catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            Log.i(TAG, e.toString());
                        }
                    }
                }
                catch (SocketException e) {
                    Log.i(TAG, e.toString());
                }
                catch (IOException e) {
                    Log.i(TAG, e.toString());
                }
            }
        });

        thread.start();
    }

    public String getLocalHostIp()
    {
        String ipaddress = "";
        try
        {
            Enumeration en = NetworkInterface
                    .getNetworkInterfaces();
            // 遍历所用的网络接口
            while (en.hasMoreElements())
            {
                NetworkInterface nif = en.nextElement();// 获得每个网络接口绑定的全部ip
                Enumeration inet = nif.getInetAddresses();
                // 遍历每个接口绑定的全部ip
                while (inet.hasMoreElements())
                {
                    InetAddress ip = inet.nextElement();
                    // 在这里若是不加isIPv4Address的判断,直接返回,在4.0上获取到的是相似于fe80::1826:66ff:fe23:48e%p2p0的ipv6的地址
                    if (!ip.isLoopbackAddress()
                            && ip instanceof Inet4Address)
                    {
                        return ipaddress = "本机的ip是" + ":" + ip.getHostAddress();
                    }
                }

            }
        }
        catch (SocketException e)
        {
            Log.e("feige", "获取本地ip地址失败");
            e.printStackTrace();
        }
        return ipaddress;

    }
}

Android权限

   <uses-permission android:name="android.permission.INTERNET">
    uses-permission>
    
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE">
    uses-permission>
    
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

发送客户端

package com.luoxiao;

import java.io.IOException;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
public class Main {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        // 广播的实现 :由客户端发出广播,服务器端接收
        String host = "192.168.8.255";// 广播地址
        int port = 9999;// 广播的目的端口
        String message = "test";// 用于发送的字符串
        try {
            InetAddress adds = InetAddress.getByName(host);
            DatagramSocket ds = new DatagramSocket();
            DatagramPacket dp = new DatagramPacket(message.getBytes(),
                    message.length(), adds, port);
            while (true) {
                ds.send(dp);
                try {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        catch (UnknownHostException e) {
            e.printStackTrace();
        }
        catch (SocketException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

接收服务器

package com.company;

import java.io.IOException;
import java.net.*;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int port = 9999;// 开启监听的端口
        DatagramSocket ds = null;
        DatagramPacket dp = null;
        byte[] buf = new byte[1024];// 存储发来的消息
        try {
            // 绑定端口的
            ds = new DatagramSocket(port);
            dp = new DatagramPacket(buf, buf.length);
            System.out.println("监听广播端口打开:");
            while (true) {
                ds.receive(dp);
                int i;
                StringBuffer sbuf = new StringBuffer();
                for (i = 0; i < 1024; i++) {
                    if (buf[i] == 0) {
                        break;
                    }
                    sbuf.append((char) buf[i]);
                }
                System.out.println("收到广播消息:" + sbuf.toString());
                try {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        catch (SocketException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

参考

https://blog.csdn.net/hustypf/article/details/8645148

http://www.javashuo.com/article/p-zplzerlj-de.html