這篇博客呢主要是兩個手機進行 Socket 通信案例的分析
(話說老孃也算寫了幾篇博客,爲什麼訪問量就是少的可憐呢……)
首先是這個案例可以實現什麼:
它包含兩個工程,一個服務端,一個客戶端,服務端的工程裏面有個按鈕,是打開服務端鏈接,客戶端有兩個按鈕,一個是鏈接服務端,一個是發送數據
什麼是 TCP/IP 協議,什麼是 Socket ???
網絡由下往上分爲:
物理層–
數據鏈路層–
網絡層– IP協議
傳輸層– TCP協議
會話層–
表示層和應用層– HTTP協議
TCP/TP協議簡稱 網絡傳輸層,主要用來傳輸數據
爲了區別不同的應用程序進程和連接,許多計算機操作系統爲應用程序與 TCP/IP 協議交互提供了套接字( Socket )接口。應用層可以和傳輸層通過 Socket 接口,區分來自不同應用程序進程或網絡連接的通信,實現數據傳輸的併發服務。
這個大神講的挺清楚的:http://www.cnblogs.com/iOS-mt/p/4264675.html
爲了讓APP正確運行,必須要保證兩個設備的網絡屬於同一個網端 (連接在了同一個WiFi上面)
服務端一共做了兩件事:
1.打開服務端等待客戶端鏈接
2.接收客戶端信息並反饋給客戶端信息
這兩個功能的實現我都把它封裝到兩個內部類裏面了
下面是這個工程的步驟
1.創建服務端 Socket 監聽服務端的鏈接
等待客戶端的鏈接是一個耗時操作,所以要放到子線程
class ServerSocketThread extends Thread {
@Override
public void run() {
try {
//創建服務端Socket
ServerSocket serverSocket = new ServerSocket();
//綁定客戶端(因爲是在同一個機子上訪問,所以IP地址一樣,直接是127.0.0.1)
serverSocket.bind(new InetSocketAddress("10.232.9.241", 1234));//服務端的IP地址
//一直等待客戶端鏈接
while (true) {
Log.e("TAG", "server_wait");
//鏈接客戶端
Socket socket = serverSocket.accept();
//這是一個監聽客戶端發送信息,並向客戶端反饋的方法,(後面講到)
connected(socket);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
步驟:
創建一個serverSocket 爲它綁定IP地址和端口號,IP地址那一行需要更改
不斷地while循環 監聽客戶端的鏈接
注意:創建SeverSocket的時候IP地址要是服務端的IP地址(我在這裏跌倒過…)
最後是可以打印出以下的log日誌的:
2.接收客戶端的信息並向客戶端反饋
同樣這裏要開啓一個子線程,因爲要不斷地接收客戶端的信息,所以這個也定義在內部類中了
class ConnectThread extends Thread {
Socket socket;//得到連接的客戶端的Socket
InputStream in = null;
OutputStream out = null;
public ConnectThread(Socket socket) {
this.socket = socket;
try {
in = socket.getInputStream();
out = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
byte[] buffer = new byte[1024];//字節數組承載讀到的字節
int bytes ;
//等待另一端發送的數據
try {
while ((bytes = in.read(buffer)) != -1) {
Log.e("TAG", "server_read:" + new String(buffer, 0, bytes));
String data = "server_read_success";
write(data.getBytes());//向客戶端寫入反饋的方法
}
} catch (IOException e) {
e.printStackTrace();
}
}
因爲要接收和向客戶端發送信息所以必須得到客戶端 socket 對象的輸入輸出流,所以在構造方法中要傳入和服務端結合的客戶端 socket
這樣就可以讀到客戶端發來的信息繫了
那麼怎麼給客戶端一個反饋呢 ???—-就是向客戶端發出信息
我把這個也放到了和服務端通信的內部類中了
//向另一端寫數據的操作
public void write(byte[] buffer) {
try {
out.write(buffer);
Log.e("TAG", "server_write " + new String(buffer));
} catch (IOException e) {
e.printStackTrace();
}
}
最後是關閉流,只需要關閉 socket 即可
//關閉的方法
public void cancle() {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
這個通信類就寫完了,裏面包含開啓
子線程(run方法中)不斷地接收客戶端發來的信息
向客戶端寫入信息
關閉流的操作
3.connected(Socket socket);方法的實現
在上面第一個內部類綁定好客戶端後有個鏈接客戶端的方法,這個方法主要是做對客戶端消息的監聽和反饋,對!就是對上面第二個類的實例化之類的操作
private void connected(Socket socket) {
if (connectThread != null) {
connectThread.cancle();
connectThread = null;
}
connectThread = new ConnectThread(socket);
connectThread.start();
Log.e("TAG", "connect success");
}
把這個方法放到第一個綁定客戶端的類裏面就行了
最後最後!! 別忘了 new ServerSocketThread().start();
源碼在這裏 :
謝謝觀看~