Android UDP Socket 网络通讯

UDP 协议以数据报作为数据的传输载体,在进行传输时 首先要把传输的数据定义成数据报(Datagram),在数据报中指明数据要到达的 Socket(主机地址 和端口号),最后将数据以数据报的形式发送出去,不负责服务器有没有收到

也就是发后不管

服务端实现

  1. 创建 DatagramSocket 指定端口号
  2. 创建 DatagramPacket
  3. 接收客户端发送的数据信息
  4. 读取数据

范例

  1. 在某个目录下创建 UDPServer.java,比如 d:\dev

    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.Enumeration;
    
    public class UDPServer {
    
        public static String getServAddr() {
    
            try {
                Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
                while (allNetInterfaces.hasMoreElements()) {
                    NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
    
                    // 去除回环接口,子接口,未运行和接口
                    if (netInterface.isLoopback() || netInterface.isVirtual() || !netInterface.isUp()) {
                        continue;
                    }
    
                    Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
                    while (addresses.hasMoreElements()) {
                        InetAddress ip = addresses.nextElement();
                        if (ip != null) {
                            // ipv4
                            if (ip instanceof Inet4Address) {
                                if (ip.getHostAddress().startsWith("192") || ip.getHostAddress().startsWith("10")
                                        || ip.getHostAddress().startsWith("172") || ip.getHostAddress().startsWith("169")) {
                                    return ip.getHostAddress();
                                }
                            }
                        }
                    }
                }
            } catch (SocketException e) {
                System.err.println("Error when getting host ip address"+ e.getMessage());
            }
    
            return "";
        }
    
        public static void main(String[] args) throws IOException {
            /*
             * 接收客户端发送的数据
             */
            // 1.创建服务器端DatagramSocket,指定端口;
            DatagramSocket socket = new DatagramSocket(12345);
    
            while ( true ) {
    
                // 2.创建数据报,用于接收客户端发送的数据
                byte[] data = new byte[1024];// 创建字节数组,指定接收的数据包的大小
                DatagramPacket packet = new DatagramPacket(data, data.length);
                // 3.接收客户端发送的数据
                System.out.println("服务器已经运行在" + getServAddr() + ":12345 ,等待客户端发送数据");
    
                socket.receive(packet);// 此方法在接收到数据报之前会一直阻塞
                // 4.读取数据
                String info = new String(data, 0, packet.getLength());
                System.out.println("我是服务器,客户端说:" + info);
    
                /*
                 * 向客户端响应数据
                 */
                // 1.定义客户端的地址、端口号、数据
                InetAddress address = packet.getAddress();
                int port = packet.getPort();
                byte[] data2 = "简单教程欢迎您!".getBytes();
                // 2.创建数据报,包含响应的数据信息
                DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);
                // 3.响应客户端
                socket.send(packet2);
            }
            // 4.关闭资源
            /socket.close();
        }
    }
    
  2. 打开终端或命令行提示符,输入以下命令运行 UDPServer.java

    javac UDPServer.java && java UDPServer
    

    如果出现下面的文字则说明服务正常启动

    服务器已经运行在 192.168.0.108:12345 ,等待客户端发送数据
    

    你的 ip 可能不同

然后客户端就可以通过 192.168.0.108:12345 访问我们的 UDP Server 了

客户端实现步骤

  1. 定义发送信息
  2. 创建 DatagramPacket,包含将要发送的信息
  3. 创建 DatagramSocket
  4. 发送数据

范例

  1. 创建一个 空的 Android 项目 cn.twle.android.UdpChat

  2. 修改 AndroidManifest.xml 添加网络权限

    <uses-permission android:name="android.permission.INTERNET"/>
    
  3. 修改 activity_main.xml 添加一个 TextView 用来显示信息

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="16dp"
        android:orientation="vertical">
    
        <TextView
            android:id="@+id/ms_chatmsg"
            android:layout_height="match_parent"
            android:layout_width="match_parent"
            android:text="" />
    
    </LinearLayout>
    
  4. 修改 MainActivity.java

    package cn.twle.android.udpchat;
    
    import android.os.Handler;
    import android.os.Message;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.widget.TextView;
    
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    public class MainActivity extends AppCompatActivity {
    
        private TextView ms_chatmsg;
        private StringBuilder builder;
    
        private Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch ( msg.what) {
                    case 0x1001:
                        ms_chatmsg.setText(builder.toString());
                        break;
                }
            }
        };
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ms_chatmsg =  (TextView) findViewById(R.id.ms_chatmsg);
    
            builder  = new StringBuilder();
    
            chat();
        }
        private void chat() {
            new Thread(new Runnable() {
                public void run() {
                    try {
    
                        /*
                         * 向服务器端发送数据
                         */
                        // 1.定义服务器的地址、端口号、数据
                        // 注意 ip 要替换成你的
                        InetAddress address = InetAddress.getByName("192.168.0.108");
                        int port = 12345;
                        byte[] data = "你好,我是客户端".getBytes();
    
                        builder.append("<<< 你好,我是客户端\n");
    
                        builder.append("看看服务器有没有啥回复\n");
    
                        handler.sendEmptyMessage(0x1001);
    
                        // 2.创建数据报,包含发送的数据信息
                        DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
                        // 3.创建DatagramSocket对象
                        DatagramSocket socket = new DatagramSocket();
                        // 4.向服务器端发送数据报
                        socket.send(packet);
    
                        /*
                         * 接收服务器端响应的数据
                         */
                        // 1.创建数据报,用于接收服务器端响应的数据
                        byte[] data2 = new byte[1024];
                        DatagramPacket packet2 = new DatagramPacket(data2, data2.length);
                        // 2.接收服务器响应的数据
                        socket.receive(packet2);
                        // 3.读取数据
                        String reply = new String(data2, 0, packet2.getLength());
    
                        builder.append(">>> 我是客户端,服务器说:" + reply);
                        handler.sendEmptyMessage(0x1001);
                        // 4.关闭资源
                        socket.close();
                    } catch (Exception e )
                    {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    
    }
    

运行之后我们的 APP 输出如下

再看一下服务器端,输出

服务器已经运行在192.168.0.108:12345 ,等待客户端发送数据
我是服务器,客户端说:你好,我是客户端

说明服务器端已经接收到了数据

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.