概述
詳細
一、准備工作
開發環境
jdk1.8
Eclipse Luna Service Release 1 (4.4.1)
運行環境:
華為榮耀6(Android4.4)、華為p9(Android7.0)
實現功能:同一局域網下,兩台設備進行tcp通信聊天。
詳情請參考博客:http://blog.csdn.net/VNanyesheshou/article/details/74896575
二、程序實現
工程截圖:
2、實現思路
Android在包Java.NET包下提供了ServerSocket和Socket類,ServerSocket用於創建服務器的Socket。Socket用於實例化客戶端的Socket。當連接成功,客戶端和服務端都會產生一個Socket實例,通過此Socket進行通信。
3、具體代碼
服務端
服務端ServerSocket的構造方法有以下幾種:
ServerSocket ():構造一個新的未綁定的ServerSocket。
ServerSocket (int port):構造一個新的ServerSocket並綁定到指定端口,如果port等於0,則端口由系統自動分配。
ServerSocket (int port, int backlog):構造一個新的ServerSocket並綁定到指定端口,並指定進入隊列的數目。如果port等於0,則端口由系統自動分配。
ServerSocket (int port, int backlog, InetAddress localAddress):構造一個新的ServerSocket並綁定到指定端口和指定的地址,並指定進入隊列的數目。如果port等於0,則端口由系統自動分配。如果localAddress為null,則可以使用任意地址。
1 開啟服務
try { //開啟服務、指定端口號 ServerSocket mServerSocket = new ServerSocket(5566); } catch (IOException e) { e.printStackTrace(); Toast.makeText(this, "服務開啟失敗", Toast.LENGTH_SHORT).show(); return; }
2調用ServerSocket的accept(),監聽連接請求,如果客戶端請求連接,則接收連接,返回Scoekt對象。
Socket mSocket = mServerSocket.accept();
3 調用Socket類的getInputStream()和getOutputStream()獲取輸入輸出流。
//獲取輸入流 mInStream = mSocket.getInputStream(); //獲取輸出流 mOutStream = mSocket.getOutputStream();
步驟4:開始發送、接收數據。
try { //發送 mOutStream.write(msg.getBytes()); mOutStream.flush(); }catch (Exception e) { e.printStackTrace(); } byte[] buffer = new byte[1024]; //循環執行read,用來接收數據。 //數據存在buffer中,count為讀取到的數據長度。 int count = mInStream.read(buffer);
步驟5:服務不再需要,則關閉服務
if(mServerSocket != null){ try { mServerSocket.close(); } catch (IOException e) { e.printStackTrace(); } }
客戶端
TCP客戶端工作具體步驟:
步驟1:創建一個Socket,連接到服務器端、指定端口號。放在子線程中運行,否則會有問題。
class SocketConnectThread extends Thread{ public void run(){ try { //指定ip地址和端口號 mSocket = new Socket(mIpAddress,mClientPort); if(mSocket != null){ //獲取輸出流、輸入流 mOutStream = mSocket.getOutputStream(); mInStream = mSocket.getInputStream(); } } catch (Exception e) { e.printStackTrace(); mHandler.sendEmptyMessage(MSG_SOCKET_CONNECTFAIL); return; } Log.i(TAG,"connect success"); mHandler.sendEmptyMessage(MSG_SOCKET_CONNECT); } }
步驟2:調用Socket類的getInputStream()和getOutputStream()獲取輸入輸出流。
具體代碼如上所示。
步驟3:發送、接收數據。(發送接收數據與服務端方法相同。)
發送數據:
private void writeMsg(String msg){ if(msg.length() == 0 || mOutStream == null) return; try { //發送 mOutStream.write(msg.getBytes()); mOutStream.flush(); }catch (Exception e) { e.printStackTrace(); } }
接收數據:(從輸入流讀取數據,需要在一個子線程中循環運行下面的方法。)
byte[] buffer = new byte[1024];//循環執行read,用來接收數據。//數據存在buffer中,count為讀取到的數據長度。int count = mInStream.read(buffer);
步驟4:關閉Socket
public void closeConnection(){ try { if (mOutStream != null) { mOutStream.close(); //關閉輸出流 mOutStream = null; } if (mInStream != null) { mInStream.close(); //關閉輸入流 mInStream = null; } if(mSocket != null){ mSocket.close(); //關閉socket mSocket = null; } } catch (IOException e) { e.printStackTrace(); } if(mReceiveThread != null){ mReceiveThread.threadExit(); mReceiveThread = null; } }
在清單文件中添加權限
AndroidManifest.xml 文件
<uses-permission android:name="android.permission.INTERNET"/>
TCP通信的使用基本就完成了,最后看一下圖片,更容易理解其通信機制。
三、運行效果
運行:
選擇作為客戶端還是服務端
作為服務端如下:(服務端設置監聽的端口號)
作為客戶端如下:(客戶端要設置連接的服務端的ip地址,及端口號)
四、其他補充
參考文章:http://blog.csdn.net/VNanyesheshou/article/details/74896575