對于普通應用的網絡子產品一般使用http文本協定,在android開發中使用http協定比較簡單,sdk已經做了很好的封裝了,具體使用方法可以參考我的這篇博文。而在遊戲開發中,可以結合使用http和socket,當然了http協定底層也是基于tcp協定的。http協定是無連接配接、無狀态的,每次連接配接隻能處理一個請求,然後就斷了,而且發一個請求需要附加額外資訊(請求行、請求頭),每次請求都需要重建立立連接配接;使用socket的好處是更高效和省流量,建立一次連接配接後,隻要不手動或者出現異常斷開,就可以一直互相發送資料,而且是直接以位元組的形式發送,不需要額外的附加資訊,缺點就是難度加大了,需要服務端和用戶端很好的配合,保證發送和讀取時資料的順序一緻。本文通過一個簡單的demo介紹開發android網遊時socket的使用方法,主要包括:android用戶端和一個簡單的使用java實作的server端,實作用戶端和服務端互相發送資料的功能。
1.用戶端代碼實作
首先建立一個android應用,名稱:androidsockettest
然後分别建立4個檔案:bytesutil.java、bytesreader.java、byteswriter.java、tcpcommunication.java,下面分别介紹這幾個檔案的用處和源碼:
bytesutil.java:包含了一些靜态工具方法:基本類型和位元組數組的互相轉換,字元串和位元組數組的互相轉換,位元組數組的指派和大小重置,對輸入流進行讀取儲存等。比較簡單,下面直接看源碼:
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<code>/**</code>
<code>author:alexzhou</code>
<code>email :[email protected]</code>
<code>date :2012-11-7</code>
<code> </code><code>**/</code>
<code>public</code>
<code>final</code> <code>class</code> <code>bytesutil {</code>
<code> </code><code>/**</code>
<code> </code><code>*整型轉換成位元組數組</code>
<code> </code><code>* @param value 要轉換的整型值</code>
<code> </code><code>* @return</code>
<code> </code><code>*/</code>
<code> </code><code>public</code>
<code>static</code> <code>byte</code><code>[] shorttobytes(</code><code>int</code>
<code>value) {</code>
<code> </code><code>byte</code>
<code>[]write = </code><code>new</code>
<code>byte</code><code>[</code><code>2</code><code>];</code>
<code> </code><code>write[</code><code>0</code><code>] = (</code><code>byte</code><code>)( (value >>> </code><code>8</code><code>) & </code><code>0xff</code><code>);</code>
<code> </code><code>write[</code><code>1</code><code>] = (</code><code>byte</code><code>)( (value >>> </code><code>0</code><code>) & </code><code>0xff</code><code>);</code>
<code> </code><code>return</code>
<code>write;</code>
<code> </code><code>}</code>
<code>static</code> <code>byte</code><code>[] inttobytes(</code><code>int</code>
<code>byte</code><code>[</code><code>4</code><code>];</code>
<code> </code><code>write[</code><code>0</code><code>] = (</code><code>byte</code><code>)( (value >>> </code><code>24</code><code>) & </code><code>0xff</code><code>);</code>
<code> </code><code>write[</code><code>1</code><code>] = (</code><code>byte</code><code>)( (value >>> </code><code>16</code><code>) & </code><code>0xff</code><code>);</code>
<code> </code><code>write[</code><code>2</code><code>] = (</code><code>byte</code><code>)( (value >>> </code><code>8</code><code>) & </code><code>0xff</code><code>);</code>
<code> </code><code>write[</code><code>3</code><code>] = (</code><code>byte</code><code>)( (value >>> </code><code>0</code><code>) & </code><code>0xff</code><code>);</code>
<code>static</code> <code>byte</code><code>[] longtobytes(</code><code>long</code>
<code>byte</code><code>[</code><code>8</code><code>];</code>
<code> </code><code>write[</code><code>0</code><code>] = (</code><code>byte</code><code>)( (value >>> </code><code>56</code><code>) & </code><code>0xff</code><code>);</code>
<code> </code><code>write[</code><code>1</code><code>] = (</code><code>byte</code><code>)( (value >>> </code><code>48</code><code>) & </code><code>0xff</code><code>);</code>
<code> </code><code>write[</code><code>2</code><code>] = (</code><code>byte</code><code>)( (value >>> </code><code>40</code><code>) & </code><code>0xff</code><code>);</code>
<code> </code><code>write[</code><code>3</code><code>] = (</code><code>byte</code><code>)( (value >>> </code><code>32</code><code>) & </code><code>0xff</code><code>);</code>
<code> </code><code>write[</code><code>4</code><code>] = (</code><code>byte</code><code>)( (value >>> </code><code>24</code><code>) & </code><code>0xff</code><code>);</code>
<code> </code><code>write[</code><code>5</code><code>] = (</code><code>byte</code><code>)( (value >>> </code><code>16</code><code>) & </code><code>0xff</code><code>);</code>
<code> </code><code>write[</code><code>6</code><code>] = (</code><code>byte</code><code>)( (value >>> </code><code>8</code><code>) & </code><code>0xff</code><code>);</code>
<code> </code><code>write[</code><code>7</code><code>] = (</code><code>byte</code><code>)( (value >>> </code><code>0</code><code>) & </code><code>0xff</code><code>);</code>
<code> </code><code>* 位元組數組轉換成整型</code>
<code> </code><code>* @param value</code>
<code>static</code> <code>int</code> <code>bytestoint(</code><code>byte</code>
<code>[]value) {</code>
<code> </code><code>int</code>
<code>i1 = (value[</code><code>0</code><code>] & </code><code>0xff</code><code>) << </code><code>24</code><code>;</code>
<code>i2 = (value[</code><code>1</code><code>] & </code><code>0xff</code><code>) << </code><code>16</code><code>;</code>
<code>i3 = (value[</code><code>2</code><code>] & </code><code>0xff</code><code>) << </code><code>8</code><code>;</code>
<code>i4 = (value[</code><code>3</code><code>] & </code><code>0xff</code><code>) << </code><code>0</code><code>;</code>
<code>(i1 | i2 | i3 | i4);</code>
<code>static</code> <code>short</code> <code>bytestoshort(</code><code>byte</code><code>[] value) {</code>
<code>s1 = (value[</code><code>0</code><code>] & </code><code>0xff</code><code>) << </code><code>8</code><code>;</code>
<code>s2 = (value[</code><code>1</code><code>] & </code><code>0xff</code><code>) << </code><code>0</code><code>;</code>
<code>(</code><code>short</code><code>)(s1 | s2);</code>
<code>static</code> <code>long</code> <code>bytestolong(</code><code>byte</code><code>[] value) {</code>
<code> </code><code>long</code>
<code>l1 = (value[</code><code>0</code><code>] & </code><code>0xff</code><code>) << </code><code>56</code><code>;</code>
<code>l2 = (value[</code><code>1</code><code>] & </code><code>0xff</code><code>) << </code><code>48</code><code>;</code>
<code>l3 = (value[</code><code>2</code><code>] & </code><code>0xff</code><code>) << </code><code>40</code><code>;</code>
<code>l4 = (value[</code><code>3</code><code>] & </code><code>0xff</code><code>) << </code><code>32</code><code>;</code>
<code>l5 = (value[</code><code>4</code><code>] & </code><code>0xff</code><code>) << </code><code>24</code><code>;</code>
<code>l6 = (value[</code><code>5</code><code>] & </code><code>0xff</code><code>) << </code><code>16</code><code>;</code>
<code>l7 = (value[</code><code>6</code><code>] & </code><code>0xff</code><code>) << </code><code>8</code><code>;</code>
<code>l8 = (value[</code><code>7</code><code>] & </code><code>0xff</code><code>) << </code><code>0</code><code>;</code>
<code>(l1 | l2 | l3 | l4 | l5 | l6 | l7 | l8);</code>
<code> </code><code>* 從指定位元組數組中拷貝部分資料</code>
<code> </code><code>* @param origin</code>
<code> </code><code>* @param from</code>
<code> </code><code>* @param to</code>
<code>static</code> <code>byte</code><code>[] copybytes(</code><code>byte</code><code>[] origin,</code><code>int</code>
<code>from,</code><code>int</code>
<code>to) {</code>
<code>len = to - from;</code>
<code> </code><code>if</code><code>(len < </code><code>0</code>
<code>|| origin.length - from <= </code><code>0</code><code>) {</code>
<code> </code><code>throw</code>
<code>new</code> <code>illegalargumentexception(</code><code>"copybytes->error arguments:to="</code><code>+to+</code><code>",from="</code><code>+from);</code>
<code> </code><code>}</code>
<code> </code><code>byte</code><code>[] ret = </code><code>new</code>
<code>byte</code><code>[len];</code>
<code> </code><code>if</code><code>(len == </code><code>0</code><code>) </code><code>return</code>
<code>ret;</code>
<code> </code><code>system.arraycopy(origin, from, ret, </code><code>0</code><code>, math.min(len, origin.length - from));</code>
<code> </code><code>* 重置位元組數組的大小,然後把原内容複制到新的位元組數組中</code>
<code> </code><code>* @param newsize</code>
<code>static</code> <code>byte</code><code>[] resizebytes(</code><code>byte</code><code>[] origin,</code><code>int</code>
<code>newsize) {</code>
<code> </code><code>if</code><code>(newsize < </code><code>0</code><code>) {</code>
<code>new</code> <code>illegalargumentexception(</code><code>"resizebytes->newsize must >= 0"</code><code>);</code>
<code>byte</code><code>[newsize];</code>
<code> </code><code>if</code><code>(newsize == </code><code>0</code><code>) </code><code>return</code>
<code> </code><code>system.arraycopy(origin,</code><code>0</code><code>,ret,</code><code>0</code><code>,math.min(origin.length, newsize));</code>
<code> </code><code>* 讀取輸入流中位元組,并儲存到指定的位元組數組中</code>
<code> </code><code>* @param is</code>
<code> </code><code>* @param data</code>
<code> </code><code>* @param off</code>
<code> </code><code>* @param len</code>
<code>static</code> <code>void</code> <code>readdata(inputstream is, </code><code>byte</code>
<code>data[], </code><code>int</code>
<code>off, </code><code>int</code>
<code>len) {</code>
<code>hasread = </code><code>0</code><code>;</code>
<code> </code><code>final</code>
<code>int</code> <code>buffer = </code><code>1024</code><code>;</code>
<code> </code><code>while</code><code>(hasread < len) {</code>
<code> </code><code>try</code>
<code>{</code>
<code> </code><code>int</code>
<code>remain = len - hasread;</code>
<code>count = is.read(data, off + hasread, remain > buffer ? buffer : remain);</code>
<code> </code><code>if</code><code>(count < </code><code>0</code><code>) </code><code>throw</code>
<code>new</code> <code>ioexception(</code><code>"readdata->read data error"</code><code>);</code>
<code> </code><code>hasread += count;</code>
<code> </code><code>} </code><code>catch</code>
<code>(ioexception e) {</code>
<code> </code><code>e.printstacktrace();</code>
<code> </code><code>}</code>
<code>}</code>
bytesreader.java:從服務端接收資料時使用,定義了一個位元組數組類型的成員變量,用來儲存從輸入流中讀取的資料。封裝了一些從該位元組數組中讀取相應資料類型的函數,源碼如下:
<code> </code><code>* 接受服務端資料時,讀取位元組并轉換到相應類型</code>
<code>final</code> <code>class</code> <code>bytesreader {</code>
<code> </code><code>private</code>
<code>final</code> <code>byte</code> <code>[]data;</code>
<code> </code><code>//位元組數組的大小</code>
<code>final</code> <code>int</code> <code>size;</code>
<code> </code><code>//目前讀取的位置</code>
<code>int</code> <code>position;</code>
<code>bytesreader(</code><code>byte</code>
<code>[]data) {</code>
<code> </code><code>this</code><code>.data = data;</code>
<code> </code><code>this</code><code>.size = data.length;</code>
<code> </code><code>this</code><code>.position = </code><code>0</code><code>;</code>
<code>byte</code><code>[] read(</code><code>int</code>
<code> </code><code>if</code><code>(len < </code><code>0</code><code>) </code><code>return</code>
<code>null</code><code>;</code>
<code> </code><code>byte</code><code>[] value = bytesutil.copybytes(data, position, position + len);</code>
<code> </code><code>this</code><code>.position += len;</code>
<code>value;</code>
<code>int</code> <code>getsize() {</code>
<code>size;</code>
<code>boolean</code> <code>isavailable() {</code>
<code>size - position > </code><code>0</code><code>;</code>
<code>short</code> <code>readshort() {</code>
<code> </code><code>byte</code><code>[] value = read(</code><code>2</code><code>);</code>
<code>bytesutil.bytestoshort(value);</code>
<code>int</code> <code>readint() {</code>
<code> </code><code>byte</code><code>[] value = read(</code><code>4</code><code>);</code>
<code>bytesutil.bytestoint(value);</code>
<code>long</code> <code>readlong() {</code>
<code> </code><code>byte</code><code>[] value = read(</code><code>8</code><code>);</code>
<code>bytesutil.bytestolong(value);</code>
<code>byte</code> <code>readbyte() {</code>
<code>value = </code><code>this</code><code>.isavailable() ? (</code><code>0xff</code>
<code>& data[position++]) : -</code><code>1</code><code>;</code>
<code>(</code><code>byte</code><code>)value;</code>
<code>byte</code><code>[] readbytes() {</code>
<code>len = readshort();</code>
<code> </code><code>//讀取大資料</code>
<code> </code><code>if</code><code>(len >= </code><code>0xffff</code><code>) {</code>
<code> </code><code>len = </code><code>this</code><code>.readint();</code>
<code>len == </code><code>0</code>
<code>? </code><code>null</code>
<code>: read(len);</code>
<code>string readutf() {</code>
<code> </code><code>byte</code><code>[] bytes = readbytes();</code>
<code> </code><code>if</code><code>(</code><code>null</code>
<code>!= bytes) {</code>
<code> </code><code>return</code>
<code>new</code> <code>string(bytes,</code><code>"utf-8"</code><code>);</code>
<code>(unsupportedencodingexception e) {</code>
byteswriter.java:向服務端發送資料時使用,跟bytesreader.java對應,也是把需要發送的資料儲存到位元組數組中,然後一次性發送給伺服器。源碼如下:
<code>date :2012-11-9</code>
<code>final</code> <code>class</code> <code>byteswriter {</code>
<code>byte</code><code>[] data;</code>
<code>int</code> <code>count;</code>
<code>byteswriter() {</code>
<code> </code><code>this</code><code>(</code><code>64</code><code>);</code>
<code>byteswriter(</code><code>int</code>
<code>size) {</code>
<code> </code><code>this</code><code>.data = </code><code>new</code>
<code>byte</code><code>[size];</code>
<code>byte</code><code>[] getbytes() {</code>
<code>this</code><code>.data.length == count ? data : count == </code><code>0</code>
<code>: bytesutil.resizebytes(</code><code>this</code><code>.data, count);</code>
<code>void</code> <code>write(</code><code>byte</code><code>[] value) {</code>
<code> </code><code>this</code><code>.write(value, </code><code>0</code><code>, value == </code><code>null</code>
<code>? </code><code>0</code>
<code>: value.length);</code>
<code>void</code> <code>write(</code><code>byte</code><code>[] d, </code><code>int</code>
<code>offset, </code><code>int</code>
<code> </code><code>if</code><code>(d == </code><code>null</code>
<code>|| len == </code><code>0</code><code>) </code><code>return</code><code>;</code>
<code>newcount = count + len;</code>
<code> </code><code>if</code><code>(newcount > </code><code>this</code><code>.data.length) {</code>
<code> </code><code>int</code>
<code>newsize = math.max(</code><code>this</code><code>.data.length << </code><code>1</code><code>, newcount);</code>
<code> </code><code>this</code><code>.data = bytesutil.resizebytes(</code><code>this</code><code>.data, newsize);</code>
<code> </code><code>system.arraycopy(d, offset, </code><code>this</code><code>.data, </code><code>this</code><code>.count, len);</code>
<code> </code><code>this</code><code>.count = newcount;</code>
<code>void</code> <code>writeint(</code><code>int</code>
<code> </code><code>this</code><code>.write(bytesutil.inttobytes(value));</code>
<code>void</code> <code>writeshort(</code><code>int</code>
<code> </code><code>this</code><code>.write(bytesutil.shorttobytes(value));</code>
<code>void</code> <code>writelong(</code><code>long</code>
<code> </code><code>this</code><code>.write(bytesutil.longtobytes(value));</code>
<code>void</code> <code>writebyte(</code><code>byte</code>
<code>newcount = count + </code><code>1</code><code>;</code>
<code> </code><code>this</code><code>.data[count] = value;</code>
<code>void</code> <code>writebytes(</code><code>byte</code><code>[] value) {</code>
<code>length = (value == </code><code>null</code>
<code> </code><code>//發送大資料時</code>
<code> </code><code>if</code><code>(length >= </code><code>0xffff</code><code>) {</code>
<code> </code><code>this</code><code>.writeshort(</code><code>0xffff</code><code>);</code>
<code> </code><code>this</code><code>.writeint(length);</code>
<code> </code><code>}</code><code>else</code>
<code> </code><code>//告訴服務端發送的資料的大小</code>
<code> </code><code>this</code><code>.writeshort(length);</code>
<code> </code><code>this</code><code>.write(value);</code>
<code>void</code> <code>writeutf(string value) {</code>
<code> </code><code>if</code><code>(value == </code><code>null</code>
<code>|| value.length() == </code><code>0</code><code>) {</code>
<code> </code><code>this</code><code>.writeshort(</code><code>0</code><code>);</code>
<code> </code><code>byte</code><code>[] bytes = </code><code>null</code><code>;</code>
<code> </code><code>try</code>
<code> </code><code>bytes = value.getbytes(</code><code>"utf-8"</code><code>);</code>
<code> </code><code>} </code><code>catch</code>
<code> </code><code>e.printstacktrace();</code>
<code> </code><code>this</code><code>.writebytes(bytes);</code>
tcpcommunication.java:上面的三個類都是輔助工具類,是給它使用的,它負責socket的建立和連接配接伺服器、讀取和發送資料,以及通過handler發送消息給ui線程更新界面顯示資料。由于我們的目的是使用socket通信,是以去掉了很多代碼,這裡隻是簡單的建立一次連接配接,發送和接收完資料後就關閉連接配接了。源碼如下:
<code>class</code> <code>tcpcommunication </code><code>implements</code>
<code>runnable {</code>
<code>socket msocket;</code>
<code>datainputstream mdis;</code>
<code>dataoutputstream mdos;</code>
<code>handler mhandler;</code>
<code>volatile</code> <code>boolean</code> <code>isrunning = </code><code>false</code><code>;</code>
<code>tcpcommunication(handler handler) {</code>
<code> </code><code>this</code><code>.mhandler = handler;</code>
<code>boolean</code> <code>isrunning() {</code>
<code>isrunning;</code>
<code>void</code> <code>startwork() {</code>
<code> </code><code>thread t = </code><code>new</code>
<code>thread(</code><code>this</code><code>);</code>
<code> </code><code>t.setpriority(thread.max_priority);</code>
<code> </code><code>t.start();</code>
<code>void</code> <code>stopwork() {</code>
<code> </code><code>this</code><code>.isrunning = </code><code>false</code><code>;</code>
<code> </code><code>@override</code>
<code>void</code> <code>run() {</code>
<code> </code><code>msocket = </code><code>new</code>
<code>socket(</code><code>"10.0.2.2"</code><code>,</code><code>8888</code><code>);</code>
<code> </code><code>mdis = </code><code>new</code>
<code>datainputstream(msocket.getinputstream());</code>
<code> </code><code>mdos = </code><code>new</code>
<code>dataoutputstream(msocket.getoutputstream());</code>
<code> </code><code>//開始發送資料到服務端</code>
<code> </code><code>byteswriter bw = </code><code>new</code>
<code>byteswriter();</code>
<code> </code><code>string username = </code><code>"alexzhou"</code><code>;</code>
<code> </code><code>string password = </code><code>"123456"</code><code>;</code>
<code>flag1 = </code><code>12345</code><code>;</code>
<code> </code><code>short</code>
<code>flag2 = </code><code>12</code><code>;</code>
<code> </code><code>long</code>
<code>flag3 = 100000000l;</code>
<code> </code><code>bw.writeutf(username);</code>
<code> </code><code>bw.writeutf(password);</code>
<code> </code><code>bw.writeint(flag1);</code>
<code> </code><code>bw.writeshort(flag2);</code>
<code> </code><code>bw.writelong(flag3);</code>
<code> </code><code>byte</code><code>[] data = bw.getbytes();</code>
<code> </code><code>byteswriter out = </code><code>null</code><code>;</code>
<code> </code><code>if</code><code>(data.length >= </code><code>0xffff</code><code>) {</code>
<code> </code><code>out = </code><code>new</code>
<code>byteswriter(data.length + </code><code>6</code><code>);</code>
<code> </code><code>out.writeshort(</code><code>0xffff</code><code>);</code>
<code> </code><code>out.writeint(data.length);</code>
<code> </code><code>}</code><code>else</code><code>{</code>
<code>byteswriter(data.length + </code><code>2</code><code>);</code>
<code> </code><code>out.writeshort(data.length);</code>
<code> </code><code>out.write(data);</code>
<code> </code><code>mdos.write(out.getbytes());</code>
<code> </code><code>//開始從服務端接收資料</code>
<code>len = mdis.readshort();</code>
<code> </code><code>if</code><code>(len == </code><code>0xffff</code><code>) {</code>
<code> </code><code>len = mdis.readint();</code>
<code> </code><code>byte</code><code>[] inputdata = </code><code>new</code>
<code> </code><code>bytesutil.readdata(mdis, inputdata, </code><code>0</code><code>, len);</code>
<code> </code><code>bytesreader br = </code><code>new</code>
<code>bytesreader(inputdata);</code>
<code> </code><code>string user_id = br.readutf();</code>
<code> </code><code>string recv_username = br.readutf();</code>
<code> </code><code>string nickname = br.readutf();</code>
<code>i = br.readint();</code>
<code>s = br.readshort();</code>
<code>l = br.readlong();</code>
<code> </code><code>string result = </code><code>"登入成功~您的資訊如下\n id:"</code><code>+user_id + </code><code>"\n使用者名:"</code>
<code>+ recv_username + </code><code>"\n昵稱:"</code>
<code>+ nickname + </code><code>"\n 序列号:"</code> <code>+ i + </code><code>"-"</code>
<code>+ s + </code><code>"-"</code>
<code>+ l;</code>
<code> </code><code>message msg = mhandler.obtainmessage();</code>
<code> </code><code>msg.what = </code><code>0</code><code>;</code>
<code> </code><code>msg.obj = result;</code>
<code> </code><code>mhandler.sendmessage(msg);</code>
<code> </code><code>mdis.close();</code>
<code> </code><code>mdos.close();</code>
<code> </code><code>msocket.close();</code>
<code>(unknownhostexception e) {</code>
<code> </code><code>};</code>
mainactivty.java的代碼比較簡單,源碼:
<code>class</code> <code>mainactivity </code><code>extends</code>
<code>activity {</code>
<code>textview mtextview;</code>
<code>button mbutton;</code>
<code>void</code> <code>oncreate(bundle savedinstancestate) {</code>
<code> </code><code>super</code><code>.oncreate(savedinstancestate);</code>
<code> </code><code>setcontentview(r.layout.activity_main);</code>
<code> </code><code>mtextview = (textview)</code><code>this</code><code>.findviewbyid(r.id.text);</code>
<code> </code><code>mbutton = (button)</code><code>this</code><code>.findviewbyid(r.id.button_send);</code>
<code> </code><code>mbutton.setonclicklistener(</code><code>new</code>
<code>onclicklistener() {</code>
<code> </code><code>@override</code>
<code> </code><code>public</code>
<code>void</code> <code>onclick(view v) {</code>
<code> </code><code>new</code>
<code>tcpcommunication(mhandler).startwork();</code>
<code> </code><code>});</code>
<code>handler mhandler = </code><code>new</code>
<code>handler() {</code>
<code> </code><code>@override</code>
<code> </code><code>public</code>
<code>void</code> <code>handlemessage(message msg) {</code>
<code> </code><code>string result = (string)msg.obj;</code>
<code> </code><code>mtextview.settext(result);</code>
<code>boolean</code> <code>oncreateoptionsmenu(menu menu) {</code>
<code> </code><code>getmenuinflater().inflate(r.menu.activity_main, menu);</code>
<code>true</code><code>;</code>
到此為止,android用戶端的代碼已經全部完成了,記得給應用添加通路網絡的權限哦:在配置檔案中添加
<code><</code><code>uses-permission</code>
<code>android:name</code><code>=</code><code>"android.permission.internet"</code>
<code>/></code>
2.服務端代碼實作
服務端的代碼比較簡單,當然了,一般在實際的開發中,服務端和用戶端不是同一個人寫的,這裡我就把用戶端裡的那幾個工具類拿來直接用了。
建立一個java項目,然後把bytesreader.java、byteswriter.java、bytesutil.java三個檔案拷貝到項目的包下,然後建立server.java,功能比較簡單,監聽8888端口,然後等待用戶端連接配接,接收和發送資料。源碼如下:
<code>final</code> <code>class</code> <code>server </code><code>implements</code>
<code>runnable{</code>
<code>serversocket mserversocket;</code>
<code>socket mclient;</code>
<code>boolean</code> <code>isrunning = </code><code>false</code><code>;</code>
<code>void</code> <code>start() {</code>
<code> </code><code>this</code><code>.isrunning = </code><code>true</code><code>;</code>
<code>void</code> <code>stop() {</code>
<code>static</code> <code>void</code> <code>main(string []args) {</code>
<code> </code><code>new</code>
<code>server().start();</code>
<code> </code><code>mserversocket = </code><code>new</code>
<code>serversocket(</code><code>8888</code><code>);</code>
<code> </code><code>system.out.println(</code><code>"start server"</code><code>);</code>
<code> </code><code>while</code><code>(isrunning) {</code>
<code> </code><code>system.out.println(</code><code>"wait client connect!!"</code><code>);</code>
<code> </code><code>mclient = mserversocket.accept();</code>
<code> </code><code>//接收用戶端發送的資料</code>
<code> </code><code>mdis = </code><code>new</code>
<code>datainputstream(mclient.getinputstream());</code>
<code> </code><code>//資料的長度</code>
<code> </code><code>if</code><code>(len == </code><code>0xffff</code><code>) {</code>
<code> </code><code>len = mdis.readint();</code>
<code> </code><code>}</code>
<code> </code><code>system.out.println(</code><code>"client data size:"</code> <code>+ len);</code>
<code> </code><code>byte</code><code>[] inputdata = </code><code>new</code>
<code> </code><code>bytesutil.readdata(mdis, inputdata, </code><code>0</code><code>, len);</code>
<code> </code><code>bytesreader br = </code><code>new</code>
<code> </code><code>string username = br.readutf();</code>
<code> </code><code>string password = br.readutf();</code>
<code> </code><code>short</code>
<code> </code><code>long</code>
<code> </code><code>system.out.println(</code><code>"username:"</code><code>+username+</code><code>";password="</code><code>+password+</code><code>"long="</code><code>+l);</code>
<code> </code><code>//向用戶端發送資料</code>
<code> </code><code>mdos = </code><code>new</code>
<code>dataoutputstream(mclient.getoutputstream());</code>
<code> </code><code>byteswriter bw = </code><code>new</code>
<code>byteswriter(</code><code>32</code><code>);</code>
<code> </code><code>string user_id = </code><code>"123456"</code><code>;</code>
<code> </code><code>string nickname = </code><code>"周江海"</code><code>;</code>
<code> </code><code>bw.writeutf(user_id);</code>
<code> </code><code>bw.writeutf(username);</code>
<code> </code><code>bw.writeutf(nickname);</code>
<code> </code><code>bw.writeint(i);</code>
<code> </code><code>bw.writeshort(s);</code>
<code> </code><code>bw.writelong(l);</code>
<code> </code><code>byte</code><code>[] data = bw.getbytes();</code>
<code> </code><code>byteswriter out = </code><code>null</code><code>;</code>
<code> </code><code>if</code><code>(data.length >= </code><code>0xffff</code><code>) {</code>
<code> </code><code>out = </code><code>new</code>
<code> </code><code>out.writeshort(</code><code>0xffff</code><code>);</code>
<code> </code><code>out.writeint(data.length);</code>
<code> </code><code>}</code><code>else</code>
<code> </code><code>out.writeshort(data.length);</code>
<code> </code><code>out.write(data);</code>
<code> </code><code>mdos.write(out.getbytes());</code>
<code> </code><code>mdos.close();</code>
<code> </code><code>mdis.close();</code>
<code> </code><code>mclient.close();</code>
<code> </code><code>} </code>
現在驗證一下,先啟動server,然後運作android用戶端應用,螢幕中間會出現textview和一個button,textview的内容是helloworld,點選button就會發送登陸資訊給服務端,然後服務端傳回資料顯示到textview上。下面分别是服務端的列印消息和用戶端的顯示截圖。

主要需要掌握基本資料類型和字元串跟位元組數組的轉換,然後按照指定的順序發送。最重要的是要注意用戶端和服務端從位元組數組讀取和往位元組數組寫入資料時的順序要對應。
下面是源碼連結:http://download.csdn.net/detail/zhoujianghai/4751981