亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android如何實現socket通信統一接口

發布時間:2021-12-13 09:13:32 來源:億速云 閱讀:152 作者:小新 欄目:開發技術

小編給大家分享一下Android如何實現socket通信統一接口,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

    Android實現socket通信統一接口,統一接口之后可以在不需要大量修改應用層代碼的情況下,使用與當前功能類似但是底層實現不同的功能,以實現的UDP與TCP兩種通信方式的接口為例。

    UDP通信與TCP通信的實現

    UDP通信

    我們在使用UDP通信方式時,我們會這樣實現

    //設置socket
    val socket = DatagramSocket()
    val serverPort = 9000
    val address = InetAddress.getByName("ip地址")
    //發送
    val bytes = message.toByteArray(Charsets.UTF_8)
    val len = bytes.size
    val sendPacket = DatagramPacket(bytes, len, address, serverPort)
    socket.send(sendPacket)
    //接收
    socket.receive(receivePacket)
    val data = String(receivePacket.data, Charsets.UTF_8)
    //處理接收到的數據
    //關閉連接
    socket.close()

    TCP客戶端通信

    我們在使用TCP客戶端通信方式時,我們會這樣實現

    //設置socket
    val serverPort = 9000
    val address = InetAddress.getByName("ip地址")
    val socket = Socket(address, serverPort)
    val input = socket.getInputStream()
    val output = socket.getOutputStream()
    //發送
    output.write(message.toByteArray(Charsets.UTF_8))
    //接收
    val len = input.read(receive)
    val data = String(receive, 0, len, Charsets.UTF_8)
    //處理接收到的數據
    //關閉連接
    socket.close()

    這樣的話,如果我們需要將應用層中的UDP連接轉換為TCP連接,就要大量地修改代碼。

    使用統一接口

    統一接口之后可以在不需要大量修改應用層代碼的情況下,使用與當前功能類似但是底層實現不同的功能。

    以之前我們實現的UDP與TCP兩種通信方式為例,要將其中任意一種轉換為另一種時,又或者有新的通信方式需要采用,每次都繁復地修改應用層代碼很明顯不是個好主意。

    我們可以簡單地分析一下這兩種通信方式,他們都要經歷初始化(設置socket)-> 發送或者接收 -> 處理數據 -> 關閉連接,那我們就可以將這些他們共有的部分抽象出來給應用層使用。

    定義接口

    新建一個Communicate.kt文件,實現Communicate接口

    interface Communicate {
        /**
         * 通信端口
         */
        var serverPort: Int
        /**
         * 通信地址
         */
        var address: String
        /**
         * 輸入編碼
         */
        var inCharset: Charset
        /**
         * 輸出編碼
         */
        var outCharset: Charset
        /**
         * 發送數據
         * @param message 數據內容
         */
        fun send(message: String)
        /**
         * 開始接收數據
         * @param onReceive 處理接收到的數據的函數,函數返回值為是否繼續接收消息.
         * 請不要在函數中使用stopReceive()函數停止接收數據,這不會起作用。
         * @return 是否開啟成功
         */
        fun startReceive(onReceive: OnReceiveFunc): Boolean
        /**
         * 停止接收數據
         */
        fun stopReceive()
        /**
         * 開啟通信,用于TCP建立連接
         * @return 是否開啟成功
         */
        fun open(): Boolean
        /**
         * 關閉通信
         */
        fun close()
    }

    上面的代碼塊中還用到了OnReceiveFunc,這用到了kotlin中的類型映射,類似于c語言中的typedef,下面是OnReceiveFunc的實現,他接收一個字符串作為參數,返回一個布爾型變量。

    typealias OnReceiveFunc = (String) -> Boolean

    在具體使用時利用kotlin的特性,可以直接寫OnReceiveFunc方法體。

    communicate.startReceive {
        binding.textView.text = it
        return@startReceive false
    }

    而在java中的使用方法如下

    communicate.startReceive(result -> {
        binding.textView.setText(result);
        return false;
    });

    注:這里的communicate是一個實現了Communicate接口的通信對象,而我們并沒有關心到底采用了什么通信方式。

    這部分中我們可以使用靜態方法來讓應用層創建對象(即選擇想要的連接方式)更加方便。

    interface Communicate {
     companion object {
         @JvmStatic
         val TCPClient: Communicate
             get() = TCP()
         @JvmStatic
         val UDP: Communicate
             get() = UDP()
     }
     //其他代碼
    }

    其中用到了@JvmStatic的注解,這讓java調用Communicate時可以少一層companion

    實現接口

    我們再實現UDPTCPClient這兩個類,他們都實現了Communicate接口。

    我沒有實現TCPServer,已經實現的兩種具體實現可以參考我的gitee倉庫

    實現應用層

    這樣一來在應用層調用就可以使用同一種風格,比如聲明一個UDP通信對象

    private val communicate = Communicate.UDP.apply {
        address = "ip地址"
        serverPort = 9000
        inCharset = Charset.forName("gb2312")
        outCharset = Charset.forName("gb2312")
        open()
    }

    而聲明一個TCPClient通信對象只需要這樣

    private val communicate = Communicate.TCPClient.apply {
        //與UDP完全一樣
    }

    而調用部分就更不用說了,完全不需要修改。這樣一來當我們需要修改當前通信方式時只需要將Communicate.UDP改為Communicate.TCPClient,極大地降低了后續修改的工作量。

    看完了這篇文章,相信你對“Android如何實現socket通信統一接口”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    定结县| 宜兴市| 贵州省| 饶平县| 北安市| 莫力| 桑日县| 三原县| 江口县| 黑水县| 安龙县| 潍坊市| 云林县| 连城县| 兴海县| 卢湾区| 盐边县| 隆德县| 芜湖县| 湖北省| 澄江县| 绿春县| 大理市| 天水市| 阜新市| 南陵县| 扎鲁特旗| 阳春市| 万年县| 新建县| 五河县| 扎兰屯市| 德清县| 承德县| 滦南县| 读书| 得荣县| 郓城县| 红桥区| 宁明县| 诏安县|