首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android Socket 通訊實作:手機當 Server 實現多裝置點對點傳輸

     編輯:程式設計綜合問答

Android 裝置間透過 Socket 通訊,一台當 Server (ServerSocket),多台當 Client (Socket),實現局域網內即時訊息/檔案傳輸。本文提供完整雙端代碼架構與關鍵點。

架構概覽


+----------------+      Wi-Fi Hotspot / LAN       +----------------+
|  Server 端      | <----------------------------> |  Client 端 x N  |
|  ServerSocket  |        TCP Socket                |  Socket         |
|  accept() 迴圈  |                                |  connect()      |
+----------------+                                +----------------+

Server 端核心代碼 (Kotlin)

class SocketServer(private val port: Int = 8888) {
    private var serverSocket: ServerSocket? = null
    private val clients = mutableListOf()
    private val executor = Executors.newCachedThreadPool()

    fun start() {
        executor.execute {
            try {
                serverSocket = ServerSocket(port)
                while (!Thread.currentThread().isInterrupted) {
                    val client = serverSocket!!.accept()  // 阻塞等待連線
                    clients.add(client)
                    executor.execute(ClientHandler(client))
                }
            } catch (e: IOException) { e.printStackTrace() }
        }
    }

    fun broadcast(msg: String) {
        clients.forEach { it.outputStream.write(msg.toByteArray()) }
    }

    inner class ClientHandler(private val socket: Socket) : Runnable {
        override fun run() {
            try {
                val input = socket.inputStream.bufferedReader()
                input.forEachLine { line ->
                    // 處理收到訊息,可再 broadcast 給其他客戶端
                    handleMessage(line)
                }
            } catch (e: IOException) { } finally { closeQuietly(socket) }
        }
    }

    fun stop() {
        serverSocket?.close()
        executor.shutdownNow()
    }
}

// AndroidManifest.xml 需權限
// 
// 
//  (開熱點需)

Client 端核心代碼

class SocketClient(private val serverIp: String, private val port: Int = 8888) {
    private var socket: Socket? = null
    private val handler = Handler(Looper.getMainLooper())

    fun connect(onConnected: () -> Unit, onMessage: (String) -> Unit, onError: (Exception) -> Unit) {
        Thread {
            try {
                socket = Socket(serverIp, port)
                handler.post(onConnected)
                val reader = socket!!.inputStream.bufferedReader()
                reader.forEachLine { line ->
                    handler.post { onMessage(line) }
                }
            } catch (e: Exception) {
                handler.post { onError(e) }
            }
        }.start()
    }

    fun send(msg: String) {
        Thread { socket?.outputStream?.write("$msg\n".toByteArray()) }.start()
    }

    fun disconnect() { socket?.close() }
}

關鍵實作細節

議題解決方案
手機開熱點WifiManager.setWifiApEnabled(null, true) (需系統簽名/Root) 或引導使用者手動開啟「攜帶式熱點」
發現 Server IP固定熱點 IP (通常 192.168.43.1) / UDP 廣播發現 / mDNS (Bonjour) / QR Code 掃描 IP
斷線重連Client 端實作指數退避重連邏輯,Server 端定期心跳檢測清理死連線
大檔案傳輸分塊發送 + 校驗和 (CRC32/MD5) + 斷點續傳 (RandomAccessFile)
編碼統一協議層統一 UTF-8,訊息以換行符 `\n` 或長度前綴分幀

現成開源庫推薦

  • KryoNet:高效序列化 + UDP/TCP,適合遊戲/即時同步。
  • Netty (Android 版):事件驅動、零拷貝、支援 WebSocket/HTTP/自定義協議。
  • Okio + OkHttp WebSocket:現代 HTTP/WS 基礎,穩定易用。
  • Nearby Connections API:Google 官方離線 P2P (藍牙/BLE/Wi-Fi Direct),無需手動開熱點。

權限配置 (Android 10+)

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
<!-- 掃描/連接 Wi-Fi Direct 需定位權限 -->
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" /> 
<!-- Android 13+ 專用 -->

提問者回饋:「Android的socket不就是java的socket麼,比如說應用什麼快傳就是開wifi熱點然後用socket啊」。掌握 Java Socket 基礎,結合 Android 生命週期管理與權限配置,即可實作穩定的裝置間通訊。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved