Kotlin網(wǎng)絡(luò)編程(4)UDP Socket 低層次網(wǎng)絡(luò)編程

  • DatagramSocket 類
  • DatagramPacket 類
  • 案例:文件上傳工具

??UDP 就像日常生活中的郵件投遞,不能保證可靠地寄到目的地。UDP 是無連接的,對系統(tǒng)資源的要求較少,UDP 可能丟包且不保證數(shù)據(jù)順序俏讹。但是對于網(wǎng)絡(luò)游戲和在線視頻等要求傳輸快、實時性高挽荡、質(zhì)量可稍差一點的數(shù)據(jù)傳輸藐石,UDP 還是非常不錯的。

??UDP Socket 網(wǎng)絡(luò)編程比 TCP Socket 編程簡單得多定拟,UDP 是無連接協(xié)議,不需要像 TCP 一樣監(jiān)聽端口且建立連接,才能進(jìn)行通信青自。

一株依、DatagramSocket 類

??java.net 包中提供了兩個類 DatagramSocketDatagramPacker,用來支持 UDP 通信延窜。DatagramSocket 用于在程序之間建立傳送數(shù)據(jù)報的通信連接恋腕。

下面是 DatagramSocket 常用的構(gòu)造函數(shù):

  • DatagramSocket()。創(chuàng)建數(shù)據(jù)報 DatagramSocket 對象逆瑞,并將其綁定到本地主機(jī)上任何可以的端口荠藤。
  • DatagramSocket(port: Int)。創(chuàng)建數(shù)據(jù)報 DatagramSocket 對象获高,并將其綁定到本地主機(jī)上的指定端口哈肖。
  • DatagramSocket(port: Int, laddr: InetAddress!)。創(chuàng)建數(shù)據(jù)報 DatagramSocket 對象念秧,并將其綁定到指定的本地地址淤井。

DatagramSocket 其他的常用函數(shù)和屬性有:

  • send(p: DatagramPacket!)。發(fā)送數(shù)據(jù)報包摊趾。
  • receive(p: DatagramPacket!)币狠。接收數(shù)據(jù)報包。
  • port 屬性砾层。返回 DatagramSocket 連接到的遠(yuǎn)程端口漩绵。
  • localPort。返回 DatagramSocket 綁定到的本地端口肛炮。
  • inetAddress 屬性:返回 DatagramSocket 連接地址止吐。
  • localAddress 屬性:返回 DatagramSocket 綁定的本地地址。
  • isClosed 屬性:判斷返回 DatagramSocket 是否處于關(guān)閉狀態(tài)铸董。
  • isConnected 屬性:判斷返回 DatagramSocket 是否處于連接狀態(tài)祟印。
  • close() 函數(shù):關(guān)閉 DatagramSocket。

??DatagramSocket 也實現(xiàn)了 AutoCloseable 接口粟害,可以通過自動資源管理技術(shù)關(guān)閉 DatagramSocket蕴忆。

二、DatagramPacket 類

??DatagramPacket 用來表示數(shù)據(jù)報包悲幅,是數(shù)據(jù)傳輸?shù)妮d體套鹅。

下面是 DatagramPacket 的構(gòu)造函數(shù):

  • DatagramPacket(buf: ByteArray!, length: Int)。構(gòu)造數(shù)據(jù)報包汰具,其中 buf 是包數(shù)據(jù)卓鹿,length 是接收包數(shù)據(jù)的長度。
  • DatagramPacket(buf: ByteArray!, length: Int, address: InetAddress!, port: Int)留荔。構(gòu)造數(shù)據(jù)報包吟孙,包發(fā)送到指定主機(jī)上的指定端口號。
  • DatagramPacket(buf: ByteArray!, offset: Int, length: Int)。構(gòu)造數(shù)據(jù)報包杰妓,其中 offset 是 buf 字節(jié)數(shù)組的偏移量藻治。
  • DatagramPacket(buf: ByteArray!, offset: Int, length: Int, address: InetAddress!, port: Int)。構(gòu)造數(shù)據(jù)報包巷挥,包發(fā)送到指定主機(jī)上的指定端口號桩卵。

DatagramPacket 常用屬性如下:

  • address。返回發(fā)往或接收該數(shù)據(jù)報包相關(guān)的主機(jī) IP 地址倍宾,屬性類型是 InetAddress雏节。
  • data。返回數(shù)據(jù)報包中的數(shù)據(jù)高职,屬性類型是 ByteArray钩乍。
  • length。返回發(fā)送或接收到數(shù)據(jù)的長度初厚,屬性類型是 Int件蚕。
  • offset。返回發(fā)送或接收到的數(shù)據(jù)的偏移量产禾,屬性類型是 Int排作。
  • port。返回發(fā)送或接收該數(shù)據(jù)報包相關(guān)的主機(jī)的端口號亚情,屬性類型是 Int妄痪。

三、案例:文件上傳工具

  • 案例服務(wù)器端 UploadServer 代碼:
fun main(args: Array<String>) {
    println("服務(wù)器端運行...")
    startServer()
}

fun startServer() {
    DatagramSocket(8080).use { socket ->
        FileOutputStream("./TestDir/subDir/src.zip").use { fos ->
            BufferedOutputStream(fos).use { bos ->
                // 準(zhǔn)備一個緩沖區(qū)
                val buffer = ByteArray(1024)

                // 循環(huán)接收數(shù)據(jù)報包
                while (true) {
                    // 創(chuàng)建數(shù)據(jù)報包對象楞件,用來接收數(shù)據(jù)
                    val packet = DatagramPacket(buffer, buffer.size)
                    // 接收數(shù)據(jù)報包
                    socket.receive(packet)
                    // 接收數(shù)據(jù)長度
                    val len = packet.length

                    if (len == 3) {
                        // 獲得結(jié)束標(biāo)志
                        val flag = String(buffer, 0, 3)
                        // 判斷結(jié)束標(biāo)志衫生,如果是bye則結(jié)束接收。
                        if (flag == "bye") {
                            break
                        }
                    }

                    // 寫入數(shù)據(jù)到文件輸出流
                    bos.write(buffer, 0, len)
                }
                println("接收完成土浸!")
            }
        }
    }
}

??與 TCP Socket 不同罪针,UDP Socket 無法知道哪些數(shù)據(jù)包是最后一個,因此需要發(fā)送方發(fā)出一個特殊的數(shù)據(jù)包黄伊,包中包含了一些特殊標(biāo)志泪酱。

  • 案例客戶端 UploadClient 代碼:
fun main(args: Array<String>) {
    println("客戶端運行...")
    startClient()
}

fun startClient() {
    DatagramSocket().use { socket ->
        FileInputStream("./TestDir/src.zip").use { fis ->
            BufferedInputStream(fis).use { input ->
                // 創(chuàng)建遠(yuǎn)程主機(jī) IP 地址對象
                val address = InetAddress.getByName("localhost")

                // 準(zhǔn)備一個緩沖區(qū)
                val buffer = ByteArray(1024)
                // 首次從文件流中讀取數(shù)據(jù)
                var len = input.read(buffer)

                while (len != -1) {
                    // 創(chuàng)建數(shù)據(jù)報包對象
                    val packet = DatagramPacket(buffer, len, address, 8080)
                    // 發(fā)送數(shù)據(jù)報包
                    socket.send(packet)
                    // 再次從文件流中讀取數(shù)據(jù)
                    len = input.read(buffer)
                }

                // 創(chuàng)建數(shù)據(jù)報對象, 一個結(jié)束上傳的數(shù)據(jù)報包
                val packet = DatagramPacket("bye".toByteArray(), 3, address, 8080)
                socket.send(packet)

                println("上傳完成!")
            }
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市还最,隨后出現(xiàn)的幾起案子墓阀,更是在濱河造成了極大的恐慌,老刑警劉巖拓轻,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件斯撮,死亡現(xiàn)場離奇詭異,居然都是意外死亡扶叉,警方通過查閱死者的電腦和手機(jī)勿锅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門帕膜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人粱甫,你說我怎么就攤上這事泳叠∽髅椋” “怎么了茶宵?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長宗挥。 經(jīng)常有香客問我乌庶,道長,這世上最難降的妖魔是什么契耿? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任瞒大,我火速辦了婚禮,結(jié)果婚禮上搪桂,老公的妹妹穿的比我還像新娘透敌。我一直安慰自己,他們只是感情好踢械,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布酗电。 她就那樣靜靜地躺著,像睡著了一般内列。 火紅的嫁衣襯著肌膚如雪撵术。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天话瞧,我揣著相機(jī)與錄音嫩与,去河邊找鬼。 笑死交排,一個胖子當(dāng)著我的面吹牛划滋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播埃篓,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼处坪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了都许?” 一聲冷哼從身側(cè)響起稻薇,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎胶征,沒想到半個月后塞椎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡睛低,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年案狠,在試婚紗的時候發(fā)現(xiàn)自己被綠了服傍。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡骂铁,死狀恐怖吹零,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拉庵,我是刑警寧澤灿椅,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站钞支,受9級特大地震影響茫蛹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜烁挟,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一婴洼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧撼嗓,春花似錦柬采、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至振湾,卻和暖如春杀迹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背押搪。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工树酪, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人大州。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓续语,卻偏偏與公主長得像,于是被迫代替她去往敵國和親厦画。 傳聞我的和親對象是個殘疾皇子疮茄,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容