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

  • TCP Socket 通信概念
  • TCP Socket 通信過(guò)程
  • Socket 類
  • ServerSocket 類
  • 案例:文件上傳工具

??TCP 是面向連接的可靠數(shù)據(jù)傳輸協(xié)議跟畅。TCP 通信過(guò)程類似于打電話鸟悴,電話接通后雙方才能通話带射,在掛斷電話之前吞杭,電話一直占線廊遍。TCP 接連一旦建立起來(lái)踪旷,會(huì)一直占用植捎,知道關(guān)閉連接衙解。此外,TCP 為了保證數(shù)據(jù)的正確性焰枢,會(huì)重發(fā)一切沒有收到的數(shù)據(jù)蚓峦,還會(huì)對(duì)數(shù)據(jù)內(nèi)容進(jìn)行驗(yàn)證并保證數(shù)據(jù)傳輸?shù)恼_順序。因此 TCP 協(xié)議對(duì)系統(tǒng)資源有很高的要求济锄。

一暑椰、TCP Socket 通信概念

??Socket 是網(wǎng)絡(luò)上的兩個(gè)程序,通過(guò)一個(gè)雙向的通信連接荐绝,實(shí)現(xiàn)數(shù)據(jù)的交流一汽。這個(gè)鏈路的一端稱為一個(gè) Socket。Socket 通常用來(lái)實(shí)現(xiàn)客戶端和服務(wù)端的連接低滩。Socket 是 TCP/IP 協(xié)議的一個(gè)十分流行的編程接口召夹,一個(gè) Socket 有一個(gè) IP 地址和一個(gè)端口號(hào)唯一確定。一旦建立連接恕沫,Socket 還會(huì)包含本機(jī)和遠(yuǎn)程主機(jī)的 IP 地址和遠(yuǎn)端口號(hào)监憎,Socket 是成對(duì)出現(xiàn)的。

二婶溯、TCP Socket 通信過(guò)程

??使用 Socket 進(jìn)行 C/S 結(jié)構(gòu)編程的通信過(guò)程如下:


TCP Socket 通信過(guò)程

??服務(wù)器端監(jiān)聽某個(gè)端口是否有連接請(qǐng)求鲸阔,此時(shí)服務(wù)器端程序處于阻塞狀態(tài)偷霉,知道客戶端向服務(wù)器端發(fā)出連接請(qǐng)求,服務(wù)器端接收客戶端請(qǐng)求褐筛,服務(wù)器會(huì)應(yīng)答請(qǐng)求并處理請(qǐng)求类少,然后將結(jié)果應(yīng)答給客戶端,這樣就會(huì)建立連接渔扎。一旦連接建立起來(lái)瞒滴,通信 Socket 可以獲得輸入輸出流對(duì)象。借助于輸入輸出流對(duì)象就可以實(shí)現(xiàn)服務(wù)器與客戶端的通信赞警,最后不要忘記關(guān)閉 Socket 和釋放一些資源(包括關(guān)閉輸入輸出流)妓忍。

三、Socket 類

??java.net 包為 TCP Socket 編程提供了兩個(gè)核心類:SocketServerSocket愧旦,分別用來(lái)表示雙向連接的客戶端和服務(wù)器端世剖。

??下面是Socket類常用的構(gòu)造函數(shù)

  • Socket(address: InetAddress!, port: Int):創(chuàng)建 Socket 對(duì)象,并指定遠(yuǎn)程主機(jī) IP 地址和端口號(hào)笤虫;

  • Socket(address: InetAddress!, port: Int, localAddr: InetAddress!, localPort: Int):創(chuàng)建 Socket 對(duì)象旁瘫,并指定遠(yuǎn)程主機(jī) IP 地址、端口號(hào)以及本機(jī)的 IP 地址 (localAddr) 和 端口號(hào) (localPort)琼蚯;

  • Socket(host: String!, port: Int):創(chuàng)建 Socket 對(duì)象酬凳,并指定遠(yuǎn)程主機(jī)名和端口號(hào),IP 地址為 null遭庶,null 表示回送地址宁仔,即 127.0.0.1

  • Socket(host: String!, port: Int, localAddr: InetAddress!, localPort: Int):創(chuàng)建 Socket 對(duì)象峦睡,并指定遠(yuǎn)程主機(jī)翎苫、端口號(hào)以及本機(jī)的 IP 地址 (localAddr) 和 端口號(hào) (localPort)。host 為主機(jī)名榨了,IP 地址為 null煎谍,null 表示回送地址,即 127.0.0.1龙屉;

??提示:“數(shù)據(jù)類型!” 表示 “平臺(tái)類型”呐粘,String! 表示 String 或 String?。什么是平臺(tái)類型转捕?

??Socket 其他的常用函數(shù)和屬性如下

  • getInputStream() 函數(shù):通過(guò)此 Socket返回輸入流對(duì)象作岖。

  • getOutputStream() 函數(shù):通過(guò)此 Socket返回輸出流對(duì)象。

  • port: Int 屬性:返回 Socket連接到的遠(yuǎn)程端口瓜富。

  • localPort: Int 屬性:返回 Socket綁定到本地端口鳍咱。

  • inetAddress 屬性:返回 Socket連接地址降盹。

  • localAddress 屬性:返回 Socket綁定的本地地址与柑。

  • isClosed 屬性:判斷返回 Socket是否處于關(guān)閉狀態(tài)谤辜。

  • isConnected 屬性:判斷返回 Socket是否處于連接狀態(tài)。

  • close() 函數(shù):關(guān)閉 Socket价捧。

??注意:Socket 與 流所占用的資源類似丑念,不能通過(guò) Java 虛擬機(jī)的垃圾收集器回收,需要程序員釋放结蟋。釋放的方式有兩種脯倚,一種是可以在 finally 代碼塊調(diào)用 close() 函數(shù)關(guān)閉 Socket,釋放流所占用的資源嵌屎。另一種是通過(guò)自動(dòng)資源管理技術(shù)釋放資源推正,SocketServerSocket 都實(shí)現(xiàn)了 AutoCloseable 接口,所以 kotlin 中可以使用 use 函數(shù)宝惰。

四植榕、ServerSocket 類

??ServerSocket 類常用的構(gòu)造函數(shù)

  • ServerSocket(port: Int, maxQueue: Int)。創(chuàng)建綁定到特定端口的服務(wù)器 Socket尼夺。maxQueue 設(shè)置連接請(qǐng)求的最大隊(duì)列長(zhǎng)度尊残,入多隊(duì)列滿時(shí),則拒絕該連接淤堵。默認(rèn)值是 50寝衫。

  • ServerSocket(port: Int)。創(chuàng)建綁定到特定端口的服務(wù)器 Socket拐邪。連接請(qǐng)求的最大隊(duì)列長(zhǎng)度是 50慰毅。

??ServerSocket 其他的常用函數(shù)和屬性如下

  • getInputStream() 函數(shù):通過(guò)此 Socket返回輸入流對(duì)象。

  • getOutputStream() 函數(shù):通過(guò)此 Socket返回輸出流對(duì)象扎阶。

  • isClosed 屬性:判斷返回 Socket是否處于關(guān)閉狀態(tài)事富。

  • isConnected 屬性:判斷返回 Socket是否處于連接狀態(tài)。

  • accept() 函數(shù):偵聽并接收到 Socket 的連接乘陪。此函數(shù)在建立連接之前一直是阻塞狀態(tài) 统台。

??ServerSocket 類本身不能直接獲得 I/O 流對(duì)象,而是通過(guò) accept() 函數(shù)返回 Socket 對(duì)象啡邑,通過(guò) Socket 對(duì)象取得 I/O 流對(duì)象贱勃,進(jìn)行網(wǎng)絡(luò)通信。另外谤逼,ServerSocket 也實(shí)現(xiàn)了 AutoCloseable 接口贵扰,通過(guò)自動(dòng)資源管理技術(shù)關(guān)閉 ServerSocket

五流部、案例:文件上傳工具

  • 服務(wù)器端代碼:
fun main(args: Array<String>?) {
    println("服務(wù)器端運(yùn)行...")
    ServerSocket(8080).use { server ->
        server.accept().use { socket ->
            BufferedInputStream(socket.getInputStream()).use { bis ->
                FileOutputStream("./TestDir/subDir/fxy.png").use { fos ->
                    bis.copyTo(fos)
                    println("接收完成戚绕!")
                }
            }
        }
    }
}

??注意:ServerSocketaccept() 函數(shù)阻塞當(dāng)前線程,所以一般會(huì)是在子線程中執(zhí)行 accept() 函數(shù)枝冀。

  • 客戶端代碼:
fun main(args: Array<String>?) {
    println("客戶端運(yùn)行...")
    Socket("127.0.0.1", 8080).use { socket ->
        BufferedOutputStream(socket.getOutputStream()).use { bos ->
            FileInputStream("./TestDir/fxy.png").use { fis ->
                fis.copyTo(bos)
                println("上傳成功舞丛!")
            }
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末耘子,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子球切,更是在濱河造成了極大的恐慌谷誓,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吨凑,死亡現(xiàn)場(chǎng)離奇詭異捍歪,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)鸵钝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門糙臼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人恩商,你說(shuō)我怎么就攤上這事弓摘。” “怎么了痕届?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵韧献,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我研叫,道長(zhǎng)锤窑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任嚷炉,我火速辦了婚禮渊啰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘申屹。我一直安慰自己绘证,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布哗讥。 她就那樣靜靜地躺著嚷那,像睡著了一般。 火紅的嫁衣襯著肌膚如雪杆煞。 梳的紋絲不亂的頭發(fā)上魏宽,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音决乎,去河邊找鬼队询。 笑死,一個(gè)胖子當(dāng)著我的面吹牛构诚,可吹牛的內(nèi)容都是我干的蚌斩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼范嘱,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼送膳!你這毒婦竟也來(lái)了员魏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤肠缨,失蹤者是張志新(化名)和其女友劉穎逆趋,沒想到半個(gè)月后盏阶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晒奕,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年名斟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了脑慧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡砰盐,死狀恐怖闷袒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情岩梳,我是刑警寧澤囊骤,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站冀值,受9級(jí)特大地震影響也物,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜列疗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一滑蚯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧抵栈,春花似錦告材、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至产艾,卻和暖如春灿渴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背胰舆。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工骚露, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缚窿。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓棘幸,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親倦零。 傳聞我的和親對(duì)象是個(gè)殘疾皇子误续,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

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

  • 7.2 面向套接字編程我們已經(jīng)通過(guò)了解Socket的接口吨悍,知其所以然,下面我們就將通過(guò)具體的案例蹋嵌,來(lái)熟悉Socke...
    lucas777閱讀 1,183評(píng)論 0 2
  • 1 網(wǎng)絡(luò)編程----TCPNo24 【 public class Server { public static...
    征程_Journey閱讀 1,262評(píng)論 0 4
  • JAVA套接字之TCP編程 1 TCP協(xié)議 TCP是面向諒解的協(xié)議育瓜。所謂連接,就是兩個(gè)對(duì)等實(shí)體為進(jìn)行數(shù)據(jù)通信而進(jìn)行...
    yanzhelee閱讀 1,150評(píng)論 0 3
  • 計(jì)算機(jī)網(wǎng)絡(luò)概述 網(wǎng)絡(luò)編程的實(shí)質(zhì)就是兩個(gè)(或多個(gè))設(shè)備(例如計(jì)算機(jī))之間的數(shù)據(jù)傳輸栽烂。 按照計(jì)算機(jī)網(wǎng)絡(luò)的定義躏仇,通過(guò)一定...
    蛋炒飯_By閱讀 1,227評(píng)論 0 10
  • 她推開窗戶,指著旋轉(zhuǎn)的星空說(shuō)——那就是你的畫腺办,那就是你的小說(shuō)焰手。 第一次讀蔡駿的小說(shuō),斷斷續(xù)續(xù)抽離和再次投入情節(jié)環(huán)境...
    任一白閱讀 359評(píng)論 1 2