接第一章介绍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