Android开发板的局域网UDP通信方案解析及客户端核心Demo实现
发表于 2026-06-27 15:02:51

在工业控制、物联网网关、安防监控等场景中,Android 开发板与局域网服务器(或 PC)之间的数据交互对实时性要求极高。在局域网环境下,UDP(User Datagram Protocol)因其低延迟、高效率、无握手开销、首部开销小等特点,成为许多实时通信系统的首选方案。本文将针对Android开发板与PC服务器之间进行局域网UDP通信的技术方案说明,方案核心是提供了一个完整的 UDP 客户端 Demo,配合标准 PC 端测试软件,能快速了解评估一款Android开发板的网络吞吐与低延迟特性。

什么是UDP通信

UDP属于TCP/IP协议族中的传输层协议,其最大的特点是不需要建立连接,数据发送时无需经过复杂的握手过程,发送端只需将数据封装成数据报并指定目标设备的IP地址和端口号即可直接发送,因此具有传输效率高、响应速度快、资源占用低等优势。在局域网环境中,UDP是一种极为高速数据传输的网络通信方式,尤其适合需要快速响应的应用场景。

虽相较于 TCP,UDP 协议具有无连接、无握手开销、首部开销小等天然优势,是局域网内高速数据传输、设备发现(OSD/ONVIF 探测)的绝佳选择。

1782529435440386.jpg

Android开发板与PC服务器 UDP通信架构的核心实现原理

本次示例DEMO采用典型的Android开发板与PC服务器之间的局域网UDP通信架构。本次整体通信链路由PC服务器、局域网网络环境以及定昌电子的Android开发板三部分组成,即“PC ←→ UDP网络 ←→ Android开发板”,其中Android开发板负责UDP数据包的发送与接收,PC端则通过网络调试助手(如NetAssist、SSCOM)或自定义服务程序完成数据监听与交互。

原理是Android开发板作为UDP客户端支持发送与接收,可封装UDP数据报发送至指定IP地址和端口的PC服务器;同时开发板监听网络端口,当接收到PC端响应数据时,立即完成解析并反馈到应用层进行处理。PC服务器则通过网络调试助手或自定义UDP服务程序监听指定端口,实现与Android开发板的数据双向传输。 

UDP通信架构.jpg

Android 客户端核心实现DEMO

Android 的网络操作必须在子线程中执行,且由于 Android 6.0+ 的权限管理,需要在 AndroidManifest.xml 中声明权限。

Step 1: 权限配置 (AndroidManifest.xml)

<!-- 允许访问网络状态和进行 network 连接 -->

<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<!-- 如果需要支持 UDP 组播/广播,可选添加 -->

<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />

Step 2: 核心通信类 UdpClientManager.java

这是一个完整的、开箱即用的 UDP 管理类,采用了线程池设计,避免频繁创建线程,且支持单例模式。

package com.example.udpdemo;

import android.util.Log;

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

import java.net.SocketException;

import java.net.UnknownHostException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class UdpClientManager {

    private static final String TAG = "UdpClientManager";

    

    private DatagramSocket mSocket;

    private ExecutorService mThreadPool;

    private boolean isListening = false;

    private OnUdpMessageListener mListener;

    public interface OnUdpMessageListener {

        void onMessageReceived(String message, String hostAddress, int port);

        void onError(Exception e);

    }

    public UdpClientManager(OnUdpMessageListener listener) {

        this.mListener = listener;

        this.mThreadPool = Executors.newFixedThreadPool(2);

        initSocket();

    }

    private void initSocket() {

        try {

            if (mSocket == null || mSocket.isClosed()) {

                mSocket = new DatagramSocket();

                Log.d(TAG, "UDP Socket 初始化成功, 本地端口: " + mSocket.getLocalPort());

            }

        } catch (SocketException e) {

            Log.e(TAG, "Socket 初始化失败", e);

            if (mListener != null) mListener.onError(e);

        }

    }

    public void sendMessage(final String msg, final String destIp, final int destPort) {

        mThreadPool.execute(new Runnable() {

            @Override

            public void run() {

                try {

                    initSocket();

                    byte[] bytes = msg.getBytes("UTF-8");

                    InetAddress address = InetAddress.getByName(destIp);

                    DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, destPort);

                    mSocket.send(packet);

                    Log.d(TAG, "已发送数据到 " + destIp + ":" + destPort + " -> " + msg);

                } catch (UnknownHostException e) {

                    Log.e(TAG, "未知主机 IP", e);

                } catch (IOException e) {

                    Log.e(TAG, "发送 IO 异常", e);

                }

            }

        });

    }

    public void startReceiveThread() {

        if (isListening) return;

        isListening = true;

        

        mThreadPool.execute(new Runnable() {

            @Override

            public void run() {

                byte[] buffer = new byte[1024 * 2];

                while (isListening) {

                    try {

                        initSocket();

                        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

                        Log.d(TAG, "开始阻塞监听来自 PC 的 UDP 回应...");

                        mSocket.receive(packet);

                        

                        String recvStr = new String(packet.getData(), 0, packet.getLength(), "UTF-8");

                        String hostIP = packet.getAddress().getHostAddress();

                        int port = packet.getPort();

                        

                        Log.d(TAG, "收到数据来自 [" + hostIP + ":" + port + "]: " + recvStr);

                        

                        if (mListener != null) {

                            mListener.onMessageReceived(recvStr, hostIP, port);

                        }

                    } catch (IOException e) {

                        Log.e(TAG, "接收异常(可能 Socket 已关闭)", e);

                    }

                }

            }

        });

    }

    public void close() {

        isListening = false;

        if (mSocket != null && !mSocket.isClosed()) {

            mSocket.close();

            mSocket = null;

        }

        if (mThreadPool != null && !mThreadPool.isShutdown()) {

            mThreadPool.shutdownNow();

        }

        Log.d(TAG, "UDP 连接已关闭, 资源已释放");

    }

}

Step 3: 在 MainActivity.java 中调用

在界面上放置两个输入框(IP 和内容)、一个“发送”按钮、一个文本框(显示接收内容)。

package com.example.udpdemo;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity implements UdpClientManager.OnUdpMessageListener {

    private EditText etTargetIp, etMessage;

    private TextView tvLog;

    private Button btnSend;

    private UdpClientManager udpManager;

    private final int TARGET_PORT = 8888;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        etTargetIp = findViewById(R.id.et_target_ip);

        etMessage = findViewById(R.id.et_message);

        tvLog = findViewById(R.id.tv_log);

        btnSend = findViewById(R.id.btn_send);

        udpManager = new UdpClientManager(this);

        udpManager.startReceiveThread();

        btnSend.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                String ip = etTargetIp.getText().toString().trim();

                String msg = etMessage.getText().toString();

                udpManager.sendMessage(msg, ip, TARGET_PORT);

            }

        });

    }

    @Override

    public void onMessageReceived(final String message, final String hostAddress, final int port) {

        runOnUiThread(new Runnable() {

            @Override

            public void run() {

                tvLog.append("\n收到 " + hostAddress + ":" + port + " -> " + message);

            }

        });

    }

    @Override

    public void onError(Exception e) {

        runOnUiThread(new Runnable() {

            @Override

            public void run() {

                tvLog.append("\n发生错误: " + e.getMessage());

            }

        });

    }

    @Override

    protected void onDestroy() {

        super.onDestroy();

        if (udpManager != null) {

            udpManager.close();

        }

    }

}

PC服务端UDP调试助手配置

验证Android开发板与PC之间的UDP通信功能,需要在PC端部署一个UDP监听服务,用于接收开发板发送的数据并向开发板回传测试消息。为了降低测试门槛,无需自行编写服务端程序,推荐使用主流的免安装调试软件:NetAssist(调试服务助手)或SSCOM。

调试软件配置步骤:

1. 协议类型:选择 UDP模式。

2. 本地 IP 地址:选择当前 PC 的局域网 IP(例如 192.168.1.100)作为监听地址。

3. 本地端口号:设置为8888(需与 Android 客户端代码中的目标端口一致)。

4. 启动UDP监听服务:点击 “连接” 或 “打开” 开始监听。

注意:测试前请确保 Android 开发板与 PC 连接在同一个路由器/交换机下(处于同网段),并检查 PC 的 Windows 防火墙,确保其允许该调试软件访问网络。

联合调试闭环验证(5分钟快速测试指南)

完成Android客户端与PC服务端配置后,即可进行完整的UDP通信联调测试,验证开发板与PC之间的数据收发功能是否正常,通常几分钟内即可完成搭建和测试。

1、硬件准备:Android开发板、PC电脑、网线、交换机或路由器

2、硬件连接:用网线将Android开发板和PC接入同一交换机或路由器,确保两端获取到同网段IP,并能够相互访问。

3、PC端准备:在PC端启动NetAssist/ SSCOM,协议类型选择UDP,本地监听端口设置为8888,并点击“打开”监听网络数据

4、开发板端:Android开发板端运行UDP通信Demo APP,在目标IP输入框中填写PC当前的局域网IP地址,输入测试内容后点击“发送”

5、收发验证:板子发送测试内容后,正常情况PC端 NetAssist 窗口立刻会收到板子传过来的字符串。在 PC 端 NetAssist 的“远程主机”栏填入板子的 IP 和随机生成的本地端口,点击发送,板子界面也将实时刷新显示接收到的内容。

UDP通信Android开发板选型

进行局域网UDP通信项目开发,比如工业视觉、工控网关、安防NVR、AI视觉终端、物联网网关等需要实时数据交互的应用场景,上面的测试采用的是定昌电子Android开发板,这块板在硬件上搭配原生网卡芯片,优化PHY层物理层硬件,UDP吞吐量能接近理论物理极限,杜绝因硬件导致的丢包,因此建议在选择硬件主板时考虑选择原生支持千兆级以太网芯片的。选择这块板的另外一个理由是定昌官方针对精简的 Linux 内核/Android 系统网络栈进行了优化定制,能减少数据包从内核态到用户态的拷贝时间,非常适合工业高频通信,以及支持 7×24 小时长时间大流量 UDP 压测不掉线。

CSDN官方微信
扫描二维码,向CSDN吐槽
微信号:CSDNnews
微博关注
【免责声明:CSDN本栏目发布信息,目的在于传播更多信息,丰富网络文化,稿件仅代表作者个人观点,与CSDN无关。其原创性以及文中陈述文字和文字内容未经本网证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本网不做任何保证或者承诺,请读者仅作参考,并请自行核实相关内容。您若对该稿件有任何怀疑或质疑,请立即与CSDN联系,我们将迅速给您回应并做处理。】