2014年1月22日 星期三

Android socket via mini USB

Socket

簡單來講socket是基於TCP/IP通訊協定所產生出來的一個傳輸介面,源自於UNIX,現在已經被廣泛的應用在通訊界面上

Socket pair

Socket的定義就是一個IP加上一個TCP/UPD的port,例如:127.0.0.1:11554
而一組連線必須要有一個Source socket及Destination socket,我們稱之為Socket pair

Socket通訊協定的原理

Socket通訊

在這裡我們使用Android當作Server端,電腦當作Client端(使用C#),透過mini USB連線

Android socket server (Java)

要在Android端建立socket server,我們可以用java內建的socket server api來實做,另外透過DataInputStream及DataOutputStream來接收及傳送資料(在這裡我們使用自定義的port:15144):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
String line;
Double testdata = 10.5;
try {
         //建立socket server, port number:15144
         ServerSocket = new ServerSocket(15144);
         while (true) {
              //等待client端連線
              Socket client = ServerSocket.accept();
              //利用DataStream傳送及接收資料
              DataInputStream in = new DataInputStream(client.getInputStream());
              DataOutputStream out = new DataOutputStream(client.getOutputStream());
//接收一行資料
              line = in.readLine();
//Delay 5
              Thread.sleep(5000);
//傳送一個Double大小的資料
              out.writeDouble(testdata);
//關閉socket
              client.close();
} catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
}
※socket server一定要包在try catch裡面做,因為有可能會丟出exception
※建議要在另外一個thread做,因為socket server會停在ServerSocket.accept()等待client連線,若是在主thread執行的話,很容易會被Android系統kill掉,而產生ANR

電腦端socket client (C#)

在這裡利用C#來建立socket client來與Android的socket server做連接,可以利用C#內建的client api來實做(在這裡我們使用自定義的port:15134):
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
byte[] rd = new byte[8];
byte data = 10;
double result;
//建立一個TCP Socket協定
Socket mSocket = new Socket(AddressFamily.InterNetwork,
 SocketType.Stream,
 ProtocolType.Tcp);
//連線至Socket server,因為是透過USB連線,所以IP位置就是127.0.0.1
mSocket.Connect(IPAddress.Parse("127.0.0.1"),int.Parse("15134"));
//傳送資料至socket server
mSocket.Send(data);
//socket server接收資料
mSocket.Receive(rd,8,0);
/**因為JavaDataOutputStream回傳回來的Double剛好與C#的相反,所以轉置陣列**/
byte[] temp = new byte[8];
temp[0] = rd[7];
temp[1] = rd[6];
temp[2] = rd[5];
temp[3] = rd[4];
temp[4] = rd[3];
temp[5] = rd[2];
temp[6] = rd[1];
temp[7] = rd[0];
//將接收到的陣列轉換回Double型態
result = BitConverter.ToDouble(temp, 0);
//關閉socket
mSocket.Close();

ADB設定

另外在連線之前,必須要設定Android的port,所以要先用透過adb來開通port:
$adb forward tcp:15134 tcp:15144
                             ↑               ↑
                       client port  server port

結語

透過以上的程式碼,就可以達到Android device與電腦溝通傳送資料,且傳輸速度又很快,所以就能夠透過USB傳輸大量的資料到電腦端,若是Android device有連到網路上的話,也可以透過IP位置及port number來直接使用網路與電腦做資料傳輸,所以socket已經漸漸的成為一個標準的傳輸協定了。

沒有留言:

張貼留言