Android UDP,androidudp
一、UDP協議全稱是使用者資料包通訊協定 ,在網路中它與TCP協議一樣用於處理資料包,是一種不需連線的協議。
1、UDP是一個無連線協定,傳輸資料之前源端和終端不建立串連;
2、不維護串連狀態,包括收髮狀態等,因此一台服務機可同時向多個客戶機傳輸相同的訊息;
3、UDP資訊包的標題很短,8個位元組,對於TCP的20個位元組資訊包的額外開銷很小;
4、輸送量不受擁擠控制演算法的調節,只受應用軟體產生資料的速率、傳輸頻寬、源端和終端主機效能的限制;
5、不保證可靠交付;
6、UDP是面向報文的。
二、UDP的代碼編程需要用到DatagramSocket類,Java使用DatagramSocket代表UDP協議的Socket,先瞭解一下如何使用這個類。
server服務端(接收資料方)建立步驟
1、產生DatagramSocket對象,參數為連接埠號碼
DatagramSocket socket = new DatagramSocket (8888);
2、byte數組用來接收資料
byte data[] = new byte[1024];
3、DatagramPackage以包形式裝載byte數組
DatagramPacket packet = new DatagramPacket(data, data.length);
4、使用DatagramPacket的receive方法接收發送方所發送的資料,是一個阻塞的方法
socket.receive(packet);
5、接收到的資料轉變化成可讀字串
String result = new String(packet.getData(), packet.getOffset(), packet.getLength());
client用戶端(發送資料方)建立步驟
1、產生DatagramSocket對象,參數為連接埠號碼
DatagramSocket socket = new DatagramSocket (8888);
2、建立一個InetAddress對象,用於確定server用戶端(資料接收方),參數為IP地址,如我的IP地址為192.168.1.103
InetAddress serverAddress = InetAddress.getByName("192.168.1.103");
3、需要發送的資料轉化為byte數組
String sendData= "hello word";byte data[] = sendData.getBytes();
4、產生一個DatagramPacket對象,包含需要發送的byte數組,byte數組長度,已設定IP地址的serverAddress,和服務端一致的連接埠號碼(這裡是8888)
DatagramPacket packet = new DatagramPacket(data, data.length, serverAddress, 8888);
5、發送資料,調用DatagramSocket對象的send方法
socket.send(packet);
三、代碼demo示範
server服務端,可以直接運行在eclipse即可
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地址。
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;@Overridepublic 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() {@Overridepublic void onClick(View arg0) {new Thread(new Runnable() {@Overridepublic 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添加許可權和註冊
<?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如下:
參考部落格:
http://www.cnblogs.com/lee0oo0/archive/2012/04/04/2431907.html
http://wang09si.blog.163.com/blog/static/170171804201303004343304/