接第一章介绍UDP通信。相较于TCP,UDP是非常轻量级的通信方式。主要运用于游戏、影视、娱乐等场合。这些场合的共同特征就是,对速度要求比较高,但是对正准备性要求,并不是很高。比如视频时,丢掉一个错误帧,并不会观影质量产生太大影响。

  这篇主要介绍Android端的UDP通信。

  假设接收的IP是192.168.0.50,监听端口是4444(如果是手机的IP可以在设置中的关于手机里面的手机状态里查看到IP信息)。  

  发送部分的代码为:

    static void sendStringByUDP(final String str, final String address, final int port) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    DatagramSocket socket = null;
                    //首先创建一个DatagramSocket对象
                    if(socket==null){
                        socket = new DatagramSocket(null);
                        socket.setReuseAddress(true);
                        socket.setBroadcast(true);
                        socket.bind(new InetSocketAddress(port));
                    }
                    //创建一个InetAddree
                    InetAddress serverAddress = InetAddress.getByName(address);
                    byte data[] = str.getBytes("utf-8");  //把传输内容分解成字节

                    //创建一个DatagramPacket对象,并指定要讲这个数据包发送到网络当中的哪个、地址,以及端口号
                    DatagramPacket packet = new DatagramPacket(data, data.length, serverAddress, port);

                    //调用socket对象的send方法,发送数据
                    socket.send(packet);
                    socket.close();
                } catch (Exception e) {

                    e.printStackTrace();

                }
            }
        }).start();
    }

 

  我们可以从上面的代码中发现,我们首先检查了,datagramsocket是否为空,如果不为空的话再新建连接。后面就是比较常规的获取byte[] ,然后构造数据包,发送数据包,关闭socket。

  接收部分代码:

    static void getStringByUDP(final int port, final OnReceiveDataListener listener) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                String dataStr = null;
                // 创建一个DatagramSocket对象,并指定监听的端口号
                DatagramSocket socket = null;
                try {
                    socket = new DatagramSocket(port);

                    // 创建一个byte数组用于接收
                    byte data[] = new byte[4 * 1024];

                    // 创建一个空的DatagramPackage对象
                    DatagramPacket packet = new DatagramPacket(data, data.length);

                    // 使用receive方法接收发送方所发送的数据,同时这也是一个阻塞的方法
                    socket.receive(packet);
                    // 得到发送过来的数据
                    dataStr = new String(packet.getData(), packet.getOffset(), packet.getLength());
                    if (listener != null) {
                        listener.onReceiveStringListener(dataStr);
                    }
                    socket.close();
                } catch (SocketException e) {

                    e.printStackTrace();

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }
        }).start();
    }

    interface OnReceiveDataListener {
        void onReceiveStringListener(String dataStr);
    }

  与发送类似,建立连接,构建数据包,连接接收数据包,将接收到的数据通过监听传出。

  看起来与前面的TCP很类似,但是在调试过程中遇到了两个坑:

  1、

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

  部分rom手机需要这么多权限才行!我也不知道为啥。。。

  2、

  如果想让这个app既接收数据,也发送数据,UDP,接收和发送的port口不能用一样的,不然会报被占用的错误。

Done

posted on 2015-12-04 16:34  Fishbonell  阅读(429)  评论(0编辑  收藏  举报