3--安卓網路程式設計之Socket程式設計
實現場景:手機A作為客戶端,手機B作為服務端,通過Socket實現資訊互動與處理。
如下圖:客戶端通過ip和埠連線伺服器,客戶端傳送hello,服務端接收後,處理成大寫傳送給客戶端,通過Toast顯示
雖然是個簡單的測試,但基本涵蓋了Socket程式設計的所有基礎知識
頁面佈局

socket程式設計1png
服務端顯示效果
開啟服務以及有裝置加入時,介面上的反應

socket程式設計2.png
socket程式設計.png

socket程式設計.png
一、服務端實現
1.服務端介面:TCPServerActivity.java
1.通過 ServerSocket
開啟服務
2.將連線的客戶端顯示在服務端介面
3.為該客戶端開啟服務執行緒
case R.id.id_btn_start_server://開啟服務 new Thread(() -> { try { //1.開啟伺服器 ServerSocket serverSocket = new ServerSocket(8080); runOnUiThread(() -> mIdTvLink.setText("服務已開啟")); mJoinRunnable = new JoinRunnable(serverSocket); //2.將連線的客戶端顯示在服務端介面 mJoinRunnable.setOnConnListener(ip -> runOnUiThread(() -> { mIdTvLink.append("\n" + ip + "已連線"); })); //3.為該客戶端開啟服務執行緒 new Thread(mJoinRunnable).start(); } catch (IOException e) { e.printStackTrace(); } }).start(); break; case R.id.id_btn_close_server://關閉服務 if (mJoinRunnable != null) { mIdTvLink.setText("服務未開啟"); mJoinRunnable.close(); } break;
2.JoinRunnable:每次客戶端加入時建立的執行緒
1.通過服務端ServerSocket獲取Socket物件
2.獲取連線的客戶端ip,並設定連線時的回撥監聽
3.通過Socket獲取輸入I流,讀取客戶端的資訊
4.通過Socket獲取輸出O流,向客戶端傳送資訊
5.進行IO流操作
/** * 作者:張風捷特烈<br/> * 時間:2018/10/14 0014:8:01<br/> * 郵箱:[email protected]<br/> * 說明:每次客戶端加入時建立的執行緒 */ public class JoinRunnable implements Runnable { private ServerSocket mServerSocket;//ServerSocket物件 private Socket mSocket;//Socket物件 public JoinRunnable(ServerSocket serverSocket) { mServerSocket = serverSocket; } @Override public void run() { InputStream is = null; OutputStream os = null; try { //1.通過服務端ServerSocket獲取Socket物件 mSocket = mServerSocket.accept(); //2.獲取連線的客戶端ip,並設定連線時的回撥監聽 String ip = mSocket.getInetAddress().getHostAddress(); if (mOnConnListener != null) { mOnConnListener.conn(ip); } //3.通過Socket獲取輸入I流,讀取客戶端的資訊 is = mSocket.getInputStream(); //4.通過Socket獲取輸出O流,向客戶端傳送資訊 os = mSocket.getOutputStream(); //5.IO操作 int len = 0; byte[] buf = new byte[1024]; while ((len = is.read(buf)) != -1) { String msg = new String(buf, 0, len).toUpperCase(); //將讀出來的資訊進行操作後返回給客戶端 os.write(("服務端發來資訊:" + msg).getBytes()); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (is != null) { is.close(); } if (os != null) { os.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * 關閉客戶端連線 */ public void close() { try { mServerSocket.close(); mSocket.close(); } catch (IOException e) { e.printStackTrace(); } } //客戶端連線時的監聽 public interface OnConnListener { void conn(String ip); } private OnConnListener mOnConnListener; public void setOnConnListener(OnConnListener onConnListener) { mOnConnListener = onConnListener; } }
二、客戶端頁:
@OnClick({R.id.id_btn_send, R.id.id_btn_setip}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.id_btn_setip: //通過ip和埠連線服務端 new Thread(() -> connServer(mIdEtIp.getText().toString(), 8080)).start(); break; case R.id.id_btn_send: //將鍵盤輸入內容傳送給服務端 mPwOut.println(mIdTcp.getText()); break; } } /** * 通過ip和埠連線服務端核心程式碼 * * @param ipip地址 * @param port 埠 */ private void connServer(String ip, int port) { try { //1.建立客戶端Socket物件(ip,埠) mSocket = new Socket(ip, port); //2.通過socket物件獲取位元組輸出流,幷包裝成PrintWriter----用於傳送給服務端資料 mPwOut = new PrintWriter(mSocket.getOutputStream(), true); //3.通過socket物件獲取位元組輸出流 InputStream is = mSocket.getInputStream(); int len = 0; byte[] buf = new byte[1024]; while ((len = is.read(buf)) != -1) { msg = new String(buf, 0, len).toUpperCase(); runOnUiThread(() -> ToastUtil.showAtOnce(TCPClientActivity.this, msg)); } } catch (IOException e) { e.printStackTrace(); } } @Override protected void onDestroy() { super.onDestroy(); if (mSocket != null) { try { mSocket.close(); } catch (IOException e) { e.printStackTrace(); } } }
後記:捷文規範
1.本文成長記錄及勘誤表
專案原始碼 | 日期 | 備註 |
---|---|---|
V0.1--無 | 2018-10-15 | ofollow,noindex">2--安卓網路程式設計之http協議簡介+小案例引入 |
2.更多關於我
筆名 | 微信 | 愛好 | |
---|---|---|---|
張風捷特烈 | 1981462002 | zdl1994328 | 語言 |
我的github | 我的簡書 | 我的CSDN | 個人網站 |
3.宣告
1----本文由張風捷特烈原創,轉載請註明
2----歡迎廣大程式設計愛好者共同交流
3----個人能力有限,如有不正之處歡迎大家批評指證,必定虛心改正
4----看到這裡,我在此感謝你的喜歡與支援