国产免费观看青青草原网站_久久精品视频色悠悠_影音先锋激情5566_日本一區二區三區免費高清在線_麻豆精品一区综合av_丰满的大屁股一区二区_男女啪啪免费网站_草莓视频app在线观看下载_午夜寂寞少妇AA片_混乱的生物课月老师后续视频

 
您現(xiàn)在的位置:首頁(yè) ? 知識(shí)庫(kù) ? 軟件開(kāi)發(fā) 軟件開(kāi)發(fā)
Java Socket與TCP IP協(xié)議棧
發(fā)布日期:2017-09-05

OSI七層模型與TCP/IP四層模型

       很多同學(xué)知道在大學(xué)課程中,我們學(xué)習(xí)的《計(jì)算機(jī)網(wǎng)絡(luò)》一書(shū)采用的是OSI七層網(wǎng)絡(luò)模型(OSI Model),但是OSI 七層模型是一種抽象模型,在操作系統(tǒng)實(shí)際實(shí)現(xiàn)中,采用的是TCP/IP四層網(wǎng)絡(luò)模型,四層模型將七層模型合并為了應(yīng)用層(Application Layer)、傳輸層(Transport Layer)、網(wǎng)絡(luò)層(Internet Layer)、鏈路層(Link Layer),使得網(wǎng)絡(luò)系統(tǒng)在具體實(shí)現(xiàn)中更加簡(jiǎn)化,OSI七層網(wǎng)絡(luò)模型與TCP/IP四層網(wǎng)絡(luò)模型以及協(xié)議對(duì)應(yīng)關(guān)系如下表所示。在計(jì)算機(jī)系統(tǒng)中,分層是一種很重要的編程思想,分層思想將系統(tǒng)的功能與責(zé)任進(jìn)行了層次化劃分,基本上所有系統(tǒng)的架構(gòu)設(shè)計(jì),都是按照層次架構(gòu)作為基本架構(gòu)來(lái)設(shè)計(jì)的。在計(jì)算機(jī)網(wǎng)絡(luò)中,相同層次具有相同的協(xié)議處理方式,下層協(xié)議上層提供服務(wù),上層協(xié)議的行為控制著下層的工作狀態(tài),層層之間責(zé)任單一,目的明確。

 

Java對(duì)于TCP/IP協(xié)議的實(shí)現(xiàn)

       在網(wǎng)絡(luò)程序開(kāi)發(fā)中,操作系統(tǒng)都為我們提供了全面 方便的應(yīng)用層網(wǎng)絡(luò)操作類(lèi)與接口,使得程序員在使用過(guò)程中無(wú)需考慮協(xié)議棧的細(xì)節(jié),而專(zhuān)心于數(shù)據(jù)的傳輸處理過(guò)程中。當(dāng)然,操作系統(tǒng)也為程序員提供了可以掌控協(xié)議細(xì)節(jié)的機(jī)會(huì),例如使用原始套接字(Raw Socket)可以控制TCP的三次握手的細(xì)節(jié)實(shí)現(xiàn)TCP SYN掃描(注意部分 Windows 7系統(tǒng)不支持原始套接字的半開(kāi)掃描)。但是在大多常規(guī)網(wǎng)絡(luò)應(yīng)用開(kāi)發(fā)中,我們都直接使用系統(tǒng)提供的應(yīng)用層接口來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)程序。這里我們羅列出在Java中常見(jiàn)的TCP/IP協(xié)議的實(shí)現(xiàn)類(lèi)或方法,如下下表所示:

 

TCP協(xié)議為什么需要三次握手

       首先我們來(lái)看一下TCP協(xié)議三次握手的具體過(guò)程(本圖選自網(wǎng)絡(luò)):

 

       第一次握手:建立連接??蛻?hù)端發(fā)送連接請(qǐng)求報(bào)文段,將SYN位置為1,Sequence Number為x;然后,客戶(hù)端進(jìn)入SYN_SEND狀態(tài),等待服務(wù)器的確認(rèn);

       第二次握手:服務(wù)器收到SYN報(bào)文段。服務(wù)器收到客戶(hù)端的SYN報(bào)文段,需要對(duì)這個(gè)SYN報(bào)文段進(jìn)行確認(rèn),設(shè)置Acknowledgment Number為x+1(Sequence Number+1);同時(shí),自己自己還要發(fā)送SYN請(qǐng)求信息,將SYN位置為1,Sequence Number為y;服務(wù)器端將上述所有信息放到一個(gè)報(bào)文段(即SYN+ACK報(bào)文段)中,一并發(fā)送給客戶(hù)端,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài);

        第三次握手:客戶(hù)端收到服務(wù)器的SYN+ACK報(bào)文段。然后將Acknowledgment Number設(shè)置為y+1,向服務(wù)器發(fā)送ACK報(bào)文段,這個(gè)報(bào)文段發(fā)送完畢以后,客戶(hù)端和服務(wù)器端都進(jìn)入ESTABLISHED狀態(tài),完成TCP三次握手。

       那么,為什么TCP協(xié)議需要三次握手?在謝希仁的《計(jì)算機(jī)網(wǎng)絡(luò)》中是這樣說(shuō)的:

       已失效的連接請(qǐng)求報(bào)文段會(huì)的產(chǎn)生在這樣一種情況下:client發(fā)出的第一個(gè)連接請(qǐng)求報(bào)文段并沒(méi)有丟失,而是在某個(gè)網(wǎng)絡(luò)結(jié)點(diǎn)長(zhǎng)時(shí)間的滯留了,以致延誤到連接釋放以后的某個(gè)時(shí)間才到達(dá)server。本來(lái)這是一個(gè)早已失效的報(bào)文段。但server收到此失效的連接請(qǐng)求報(bào)文段后,就誤認(rèn)為是client再次發(fā)出的一個(gè)新的連接請(qǐng)求。于是就向client發(fā)出確認(rèn)報(bào)文段,同意建立連接。假設(shè)不采用“三次握手”,那么只要server發(fā)出確認(rèn),新的連接就建立了。由于現(xiàn)在client并沒(méi)有發(fā)出建立連接的請(qǐng)求,因此不會(huì)理睬server的確認(rèn),也不會(huì)向server發(fā)送數(shù)據(jù)。但server卻以為新的運(yùn)輸連接已經(jīng)建立,并一直等待client發(fā)來(lái)數(shù)據(jù)。這樣,server的很多資源就白白浪費(fèi)掉了。采用“三次握手”的辦法可以防止上述現(xiàn)象發(fā)生。例如剛才那種情況,client不會(huì)向server的確認(rèn)發(fā)出確認(rèn)。server由于收不到確認(rèn),就知道client并沒(méi)有要求建立連接。

       換句話(huà)說(shuō),TCP之所以采用三次握手建立連接的機(jī)制,是為了防止已失效的連接請(qǐng)求報(bào)文段突然又傳送到了服務(wù)端,因而產(chǎn)生錯(cuò)誤。在網(wǎng)絡(luò)中不能確保數(shù)據(jù)包的一定可以發(fā)送成功,也不能確保數(shù)據(jù)包的發(fā)送順序和到達(dá)順序一致,三次握手機(jī)制避免了客戶(hù)端與服務(wù)器之間在建立連接時(shí)可能因丟包而造成的一端 無(wú)法感知另一端狀態(tài)的現(xiàn)象。關(guān)于TCP協(xié)議的四次揮手過(guò)程與原因與三次握手完全類(lèi)同,這里就不說(shuō)明了,關(guān)于TCP連接的關(guān)閉,后文將分析一個(gè)相關(guān)問(wèn)題:TCP半關(guān)閉現(xiàn)象(Half-Close),這里我們先來(lái)看一下Java中如何使用Socket類(lèi)建立一個(gè)TCP連接的過(guò)程。

Java中TCP通信的相關(guān)實(shí)現(xiàn)

      在上節(jié)我們分析了TCP協(xié)議建立連接,數(shù)據(jù)傳輸以及關(guān)閉連接的具體實(shí)現(xiàn)方式,而在實(shí)際的開(kāi)發(fā)中,程序員只需了解TCP協(xié)議是一種可靠的傳輸協(xié)議即可實(shí)現(xiàn)數(shù)據(jù)在客戶(hù)端與服務(wù)器之間穩(wěn)定的傳輸。在Java中,提供了Socket與SocketServer類(lèi)來(lái)實(shí)現(xiàn)TCP服務(wù)器與客戶(hù)端的相關(guān)功能,一次正常的TCP通信其大致流程可以分為四步(BIO模式):

  1. 服務(wù)器端(ServerSocket)綁定監(jiān)聽(tīng)端口,等待客戶(hù)端的TCP的連接(ServerSocket.accept())

  2. 客戶(hù)端(Socket)通過(guò)IP地址與端口連接服務(wù)器監(jiān)聽(tīng)端口(Socket.Connect()),連接成功后服務(wù)器端返回表示該TCP連接的Socket對(duì)象。

  3. 客戶(hù)端與服務(wù)器通過(guò)打開(kāi)Socket對(duì)象的InputStream和OutputStream數(shù)據(jù)流,實(shí)現(xiàn)數(shù)據(jù)的傳輸工作(Java將I/O相關(guān)的操作都提供了流操作接口,網(wǎng)絡(luò)接口操作方式也一樣)。

  4. 客戶(hù)端與服務(wù)器完成數(shù)據(jù)傳輸,關(guān)閉數(shù)據(jù)流,關(guān)閉TCP連接(Socket.close())。

下圖是Socket的通行模型圖:

 

       這里有個(gè)問(wèn)題,TCP的三次握手是在Socket的哪一步中實(shí)現(xiàn)?在ServerSocket.accept()與Socket.Connect()的過(guò)程中實(shí)現(xiàn)的,在客戶(hù)端通過(guò)Connect()接口連接服務(wù)器時(shí),操作系統(tǒng)底層的tcp/ip協(xié)議棧便開(kāi)始了發(fā)送SYN包,回復(fù)SYN+1等TCP的三次握手過(guò)程,只有三次握手成功,ServerSocket.accept()才會(huì)返回一個(gè)合法的Scoket對(duì)象,客戶(hù)端Socket.Connect()函數(shù)會(huì)正常返回,如果三次握手失敗,客戶(hù)端Socket.Connect()會(huì)拋出IOException異常。

       這里需要注意,具體的三次握手協(xié)議細(xì)節(jié)的實(shí)現(xiàn),也不是在java中實(shí)現(xiàn)的,java只是運(yùn)行在jvm虛擬機(jī)上的語(yǔ)言,具體的實(shí)現(xiàn)是由宿主主機(jī)的TCP/IP協(xié)議棧實(shí)現(xiàn)的,java只是通過(guò)虛擬機(jī)調(diào)用了這些宿主主機(jī)提供的方法而已。

TCP半關(guān)閉現(xiàn)象(Half-Close)

有TCP服務(wù)器與客戶(hù)端應(yīng)用程序開(kāi)發(fā)經(jīng)驗(yàn)的同學(xué)應(yīng)該遇到過(guò)一個(gè)問(wèn)題,那就是服務(wù)器端突然崩潰(kill 掉服務(wù)器進(jìn)程),查看系統(tǒng)中的網(wǎng)絡(luò)連接時(shí),發(fā)現(xiàn)TCP客戶(hù)端的狀態(tài)還是處于連接狀態(tài)(ESTABLISHED),而該TCP連接實(shí)際已經(jīng)失效了,這就是TCP的Half-Close 現(xiàn)象。如果應(yīng)用程序判斷與服務(wù)器連接狀態(tài)的方法依賴(lài)于TCP的連接狀態(tài),客戶(hù)端將會(huì)一直認(rèn)為與服務(wù)器的TCP連接是正常的,只有在客戶(hù)端向服務(wù)器發(fā)送數(shù)據(jù)時(shí),才能發(fā)現(xiàn)TCP連接對(duì)應(yīng)的套接字失效了。之所以產(chǎn)生Half-Close現(xiàn)象就是由于客戶(hù)端與服務(wù)器之間沒(méi)有通過(guò)四次揮手的方式關(guān)閉TCP連接,在服務(wù)器的突然下線(xiàn)會(huì)造成客戶(hù)端無(wú)法立即感知的問(wèn)題。有同學(xué)會(huì)問(wèn),不是有超時(shí)時(shí)間嗎,一旦超時(shí),客戶(hù)端不就可以感知到服務(wù)器已經(jīng)下線(xiàn)了嗎?不錯(cuò),系統(tǒng)的協(xié)議棧實(shí)現(xiàn)具有超時(shí)時(shí)間的機(jī)制,但是在windows系統(tǒng)下,這個(gè)超時(shí)時(shí)間默認(rèn)是2小時(shí)(作者未考證linux下的keepAlive時(shí)間)。

那么如何避免Half-Close現(xiàn)象?

  1. 首先進(jìn)行再使用完tcp連接后,一定要將套接字close掉。

  2. 添加心跳包機(jī)制,服務(wù)器與客戶(hù)端之間的連接保持機(jī)制不應(yīng)該依賴(lài)套接字的狀態(tài),而應(yīng)該在TCP協(xié)議之上設(shè)計(jì)心跳包機(jī)制,例如每5分鐘,客戶(hù)端與服務(wù)器之間通過(guò)發(fā)送心跳包來(lái)感知對(duì)方的存在。

  3. TCP Server應(yīng)該實(shí)現(xiàn)JVM的關(guān)閉鉤子(Runtime.addShutdownHook()),主動(dòng)關(guān)閉所有TCP連接,清理占用資源,JVM關(guān)閉鉤子的使用方式如下所:

 

總結(jié)

       TCP協(xié)議作為可靠傳輸協(xié)議,是所有協(xié)議中最常用的協(xié)議,什么?最常用的協(xié)議不是HTTP嗎?HTTP協(xié)議只是TCP協(xié)議的應(yīng)用協(xié)議而已。TCP協(xié)議相關(guān)的開(kāi)發(fā)難點(diǎn)在于服務(wù)器端的開(kāi)發(fā),需要考慮并發(fā)性能,本文以講解了TCP的協(xié)議為主,因此只采用了BIO模式進(jìn)行分析,在之后的文章中將會(huì)分析高并發(fā)的TCP服務(wù)器的實(shí)現(xiàn)原理。

  • 1.公司登記注冊(cè)于2003年1月27日,清遠(yuǎn)市桑達(dá)電子網(wǎng)絡(luò)媒體有限公司
    2.公司2006年起成為清遠(yuǎn)市政府定點(diǎn)協(xié)議供貨商,電子采購(gòu)供貨商
    3.公司2007年被清遠(yuǎn)市相關(guān)政府部門(mén)評(píng)為安防行業(yè)狀元
    4.公司2007年起成為長(zhǎng)城電腦清遠(yuǎn)如意服務(wù)站(SP368)
    5.公司2007年承建清遠(yuǎn)市橫河路口電子警察工程,開(kāi)創(chuàng)清遠(yuǎn)電子警察先河。
  • 6.公司2007年起成為IBM合作伙伴、公司2010年底成為金蝶軟件清遠(yuǎn)金牌代理(伙伴編號(hào):30030013)
    7.公司組團(tuán)隊(duì)參加南方都市報(bào)組織的創(chuàng)富評(píng)選,獲廣東80強(qiáng)。公司申請(qǐng)多項(xiàng)軟件著作權(quán)、專(zhuān)利權(quán)
    8.2016年起公司成為粵東西北地區(qū)為數(shù)不多的雙軟企業(yè),確立“讓軟件驅(qū)動(dòng)世界,讓智能改變生活!"企業(yè)理想
    9.2016-01-29更名為廣東互動(dòng)電子網(wǎng)絡(luò)媒體有限公司
    10.2021-01-13更名為廣東互動(dòng)電子有限公司
  • 投資合作咨詢(xún)熱線(xiàn)電話(huà):0763-3391888 3323588
  • 做一個(gè)負(fù)責(zé)任的百年企業(yè)! 天行健,君子以自強(qiáng)不息;地勢(shì)坤,君子以厚德載物;
    為用戶(hù)創(chuàng)造價(jià)值! 讓軟件驅(qū)動(dòng)世界; 讓智能改變生活; 超越顧客期望,幫助顧客成功;
    對(duì)客戶(hù)負(fù)責(zé),對(duì)員工負(fù)責(zé),對(duì)企業(yè)命運(yùn)負(fù)責(zé)!幫助支持公司的客戶(hù)成功;幫助忠誠(chéng)于公司的員工成功!
  • 聯(lián)系電話(huà):0763-3391888 3323588 3318977
    服務(wù)熱線(xiàn):18023314222 QQ:529623964
  • 工作QQ:2501204690 商務(wù)QQ: 602045550
    投資及業(yè)務(wù)投訴QQ: 529623964
    微信:小米哥 微信號(hào):qysed3391888
    騰訊微博:桑達(dá)網(wǎng)絡(luò)-基石與起點(diǎn)
  • E-MAIL:222#QYSED.CN ok3391888#163.com (請(qǐng)用@替換#)
在線(xiàn)客服
  • 系統(tǒng)集成咨詢(xún)
    點(diǎn)擊這里給我發(fā)消息
  • 網(wǎng)站\微信\軟件咨詢(xún)
    點(diǎn)擊這里給我發(fā)消息
  • 售后服務(wù)
    點(diǎn)擊這里給我發(fā)消息
  • 投資合作
    點(diǎn)擊這里給我發(fā)消息