Android中基于TCP协议的网络通信之使用Socket进行通信
TCP協議被稱為一種端到端的協議。這是因為它為兩臺計算機的連接起到了重要作用:當一臺計算機需要與另一臺計算機進行接連時,TCP協議會他們之間建立一個連接:用于發送和接收數據的虛擬鏈路。
TCP協議負責收集這些信息包,并將其按適當的順序放好傳送,在接收端收到后再將其正確地還原。TCP協議確保了數據包在傳送中準確無誤。TCP協議使用重發機制:當一個通信實體發送一個消息給另一個通信實體后,需要收到另一個通信實體的確認信息,如果沒有收到另一個通信實體的確認信息,則會重發剛才發送的消息??梢酝ㄟ^下面的圖例來簡單了解TCP協議控制兩個通信實體互相通信的過程:
Java中能接收其他通信實體連接請求的類是ServerSocket,ServerSocket對象用來監聽來自客戶端的Socket連接,如果沒有連接,它將一直處于等待狀態。
根據上面的示意圖,可以看出我們至少需要兩個計算機設備才能進行通信。一個是服務器端,一個客戶端。在這里可能有人會說:那兩個人聊QQ、微信的時候兩個都是客戶端啊。不錯,的確兩個都是客戶端。但是,要知道,這兩個客戶端都要和騰訊的服務器連接才能通信。好了,下面我們就來用代碼來做一個綜述。
首先是服務器端(Java程序,運行于PC):
public class SimpleServer {public static void main(String[] args) throws IOException{ServerSocket ss = new ServerSocket(30000);while (true) {Socket s = ss.accept();OutputStream os = s.getOutputStream();os.write(("我是william的忠實服務器!" + Calendar.getInstance().getTimeInMillis()).getBytes("utf-8"));os.close();s.close();}} }這里我用的端口號是30000,一般來說我們推薦使用1024以上的端口號,主要是為了避免與其他的應用程序的通用端口發生沖突。
這里我們用了一個死循環來監聽來自客戶端的連接信息。這里我們是把當前毫秒時間傳給了Socket的outputStream。這里一點需要注意,那就是我用了一個.getBytes("utf-8")。這是因為,我們的服務器端是運行在PC上,一般是Windows主機,當直接使用PrintStream輸出字符串時默認使用系統平臺的字符串(GBK)編碼,但客戶端都是Android程序,運行于Linux平臺,因為客戶端讀取網絡數據時默認使用UTF-8字符集進行解碼,這樣就會造成亂碼。
----------------------------------------------------------------------------------------------------------------------------------------------------------
下面是客戶端程序(Android程序,運行于Android機):
Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {if (msg.what == 123) {try {Socket socket = new Socket("192.168.1.105", 30000);BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));String line = reader.readLine();TextView showTextView = (TextView) findViewById(R.id.activity_simple_client_textview);showTextView.setText("來自服務器的數據:" + line);reader.close();socket.close();} catch (Exception e) {e.printStackTrace();}}};};這里只提供了在Handler線程中的關鍵代碼,因為在UI線程的部分非常簡單,這里不給出代碼,完整代碼后面會有接連源碼下載。
在客戶端我們使用了IP為192.168.1.105的主機,因為筆者的PC就是這個IP。如果你的電腦你不知道怎么查看IP或是你的IP地址是設置為自動獲取IP地址,那么可以使用下圖的方法(在開始菜單下輸入cmd進入命令提示符窗口):
進入cmd的方法:
另外如果你需要修改你的服務器端程序,并且要運行修改后的程序,你可能會遇到這樣的一種情況:
遇到這種情況,不是你的程序修改的時候有問題。而是因為這個時候,你的服務器端程序里寫了一個死循環,這個死循環會一直在運行。我們可以通過任務管理器查看到這個進程還在運行著,如下:
我們只在kill掉這個進程,然后再運行服務器程序,這樣就可以了。
運行程序,如下結果:
本博客參考資料:《瘋狂Android講義》
這里是我的程序源碼(服務器端和客戶端):點擊下載源碼
總結
以上是生活随笔為你收集整理的Android中基于TCP协议的网络通信之使用Socket进行通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android Wifi开发之WifiC
- 下一篇: Android在ListView中嵌套一