Android UDP

轉自: 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如下:

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章