转自: https://www.cnblogs.com/liqw/p/4867657.html
一、UDP协议全称是用户数据报协议 ,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。
1、UDP是一个无连接协议,传输数据之前源端和终端不建立连接;
2、不维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息;
3、UDP信息包的标题很短,8个字节,对于TCP的20个字节信息包的额外开销很小;
4、吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制;
5、不保证可靠交付;
6、UDP是面向报文的。
二、UDP的代码编程需要用到DatagramSocket类,Java使用DatagramSocket代表UDP协议的Socket,先了解一下如何使用这个类。
server服务端(接收数据方)创建步骤
1、生成DatagramSocket对象,参数为端口号
1 | DatagramSocket socket = new DatagramSocket (8888); |
2、byte数组用来接收数据
1 | byte data[] = new byte[1024]; |
3、DatagramPackage以包形式装载byte数组
1 | DatagramPacket packet = new DatagramPacket(data, data.length); |
4、使用DatagramPacket的receive方法接收发送方所发送的数据,是一个阻塞的方法
1 | socket.receive(packet); |
5、接收到的数据转变化成可读字符串
1 | String result = new String(packet.getData(), packet.getOffset(), packet.getLength()); |
client客户端(发送数据方)创建步骤
1、生成DatagramSocket对象,参数为端口号
1 | DatagramSocket socket = new DatagramSocket (8888); |
2、创建一个InetAddress对象,用于确定server客户端(数据接收方),参数为IP地址,如我的IP地址为192.168.1.103
1 | InetAddress serverAddress = InetAddress.getByName("192.168.1.103"); |
3、需要发送的数据转化为byte数组
1 2 | String sendData= "hello word";byte data[] = sendData.getBytes(); |
4、生成一个DatagramPacket对象,包含需要发送的byte数组,byte数组长度,已设置IP地址的serverAddress,和服务端一致的端口号(这里是8888)
1 | DatagramPacket packet = new DatagramPacket(data, data.length, serverAddress, 8888); |
5、发送数据,调用DatagramSocket对象的send方法
1 | socket.send(packet); |
三、代码demo演示
server服务端,可以直接运行在eclipse即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;public class UDPServer { public static void main(String[] args) throws IOException { DatagramSocket socket = null; try { socket = new DatagramSocket(8888); } catch (Exception e) { e.printStackTrace(); } while (true) { byte data[] = new byte[1024]; DatagramPacket packet = new DatagramPacket(data, data.length); socket.receive(packet); String result = new String(packet.getData(), packet.getOffset(), packet.getLength()); System.out.println("receive client's data: " + result); } }} |
若多次运行会提示错误:Address already in use: Cannot bind,关掉之前开启的即可。
Android客户端代码demo演示,需要注意的是端口号是与服务端一致的,IP地址是服务端的IP地址。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import android.app.Activity;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class UDPActivity extends Activity { private Button bt_send_data = null; DatagramSocket socket = null; InetAddress serverAddress = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); bt_send_data = new Button(this); bt_send_data.setText("发送"); setContentView(bt_send_data); try { socket = new DatagramSocket(8888); serverAddress = InetAddress.getByName("192.168.1.101"); } catch (Exception e) { e.printStackTrace(); } bt_send_data.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { new Thread(new Runnable() { @Override public void run() { try { String sendData = "hello world"; byte data[] = sendData.getBytes(); DatagramPacket packet = new DatagramPacket(data, data.length, serverAddress, 8888); socket.send(packet); } catch (Exception e) { e.printStackTrace(); } } }).start(); } }); }} |
在AndroidManifest.xml添加权限和注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.libill.demos" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="10" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppStartTheme" > <activity android:name="com.liqw.demos.activity.UDPServerActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application></manifest> |
这样即可跑起demo做测试了。先运行服务端,再点击发送4次,服务端的log如下:

513

被折叠的 条评论
为什么被折叠?



