概述
詳細
一、准備工作
開發環境
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
