999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于TCP的Java Socket網(wǎng)絡(luò)連接過程要點分析

2023-08-26 04:33:15李檢輝
電腦知識與技術(shù) 2023年20期

李檢輝

關(guān)鍵詞:Java;TCP;三次握手;accept隊列;多線程

中圖分類號:TP393 文獻標識碼:A

文章編號:1009-3044(2023)20-0103-03

在網(wǎng)絡(luò)分層里,基于Java的套接字(Socket) 網(wǎng)絡(luò)編程應(yīng)用屬于應(yīng)用層。網(wǎng)絡(luò)通信雙方的兩個應(yīng)用程序在應(yīng)用層面上各創(chuàng)建一個Socket,并通過Socket建立一個雙向的通信連接以實現(xiàn)應(yīng)用層面數(shù)據(jù)的交換[1]。應(yīng)用程序的Socket并不是直接訪問主機通信模塊進行數(shù)據(jù)交換,而是通過調(diào)用操作系統(tǒng)提供的Socket API接口來請求數(shù)據(jù)傳輸,并通過這個接口選擇傳輸層提供的TCP協(xié)議或UDP協(xié)議來完成通信。TCP協(xié)議要求在真正的數(shù)據(jù)傳輸前雙方先完成三次“預(yù)通信”連接過程,即三次握手,用于確認傳輸通道是否正常,并建立一條虛連接,然后傳送數(shù)據(jù),且通信結(jié)束時還需要拆除連接[2]。由于UDP是不面向連接的協(xié)議,這里不進行分析。

在Java網(wǎng)絡(luò)編程通信模型里,TCP虛連接請求由客戶端(Client)發(fā)起,如圖1所示。

1) 在第一次握手中,由客戶端發(fā)起SYN報文,服務(wù)端收到該報文后,第一次握手成功;

2) 接著,服務(wù)端發(fā)起第二次握手,向客戶端發(fā)送SYN+ACK 報文,客戶端收到該報文后,第二次握手成功;

3) 最后,由客戶端發(fā)起第三次握手,向服務(wù)端發(fā)送ACK報文,服務(wù)端收到該報文,便完成三次握手,雙方建立一條TCP連接。

那么,在Java Socket通信程序中,三次握手是否由Socket應(yīng)用程序完成,三次握手是何時開始,何時結(jié)束,程序是如何完成這些步驟的?這些是本文要探討的主要問題。

1 服務(wù)端監(jiān)聽客戶端發(fā)起連接

Java程序通過類ServerSocket創(chuàng)建服務(wù)端,并通過調(diào)用bind()方法綁定服務(wù)器地址。一臺主機可以同時提供多個服務(wù),這些不同服務(wù)的IP地址是相同的,因此需要通過不同的端口來區(qū)別不同的服務(wù)[3]。創(chuàng)建服務(wù)器的代碼如下:

SocketAddress server_addr =new InetSocketAddress“( 192.168.1.2”,5000);

ServerSocket ss=new ServerSocket();

ss.bind(server_addr,4);

或者直接通過構(gòu)造方法new ServerSocket(5000,4) 綁定本地端口,其中“192.168.1.2”為服務(wù)端的IP 地址,5000為端口。

構(gòu)造方法及bind()方法中的數(shù)值4 是形式參數(shù)backlog的實值,表示最大連接數(shù)為4。操作系統(tǒng)將綁定某個指定端口的入站連接請求,存儲在一個先進先出的隊列中。后期,服務(wù)器在處理隊列中的連接請求時會調(diào)用accept()方法,所以,這個隊列也被稱為ac?cept隊列,不同的操作系統(tǒng)對accept隊列的長度設(shè)定會有所不同。設(shè)置backlog值是在應(yīng)用程序?qū)用嬖O(shè)定accept 隊列的大小。在SeverSocket 類的源碼中, 對backlog設(shè)定了默認值50,代碼如下:

public void bind(SocketAddress endpoint) throwsIOException {

bind(endpoint, 50);

}

如果在綁定端口時沒有給定這個參數(shù)值,即調(diào)用另一個重載方法ss.bind(server_addr),程序則會將backlog的值自動設(shè)定為默認值50。或者綁定端口時給定的backlog4的值小于1時,程序也會將這個值重新設(shè)置為50。方法void bind(SocketAddress endpoint,int backlog)中的相關(guān)代碼如下:

if (backlog < 1)

backlog = 50;

bind()方法在執(zhí)行時,首先會綁定服務(wù)端地址(IP 地址和端口),接著會調(diào)用listen()方法傳遞backlog的值,以設(shè)置最大連接數(shù),并開始進入端口監(jiān)聽狀態(tài),以等待客戶端的連接。此時,服務(wù)端操作系統(tǒng)會開始響應(yīng)到達該端口連接請求。當有客戶端連接服務(wù)端并完成三次握手后,服務(wù)端則會將此連接放入accept隊列,等待服務(wù)端調(diào)用accept()方法從該隊列中取出并進行后期通信。如果accept隊列中存儲的未處理的連接數(shù)目達到設(shè)定的backlog值,即隊列滿了,那么,服務(wù)端將會拒絕新的客戶端的連接請求。

2 客戶端觸發(fā)第一次握手

客戶端可以通過如下代碼連接服務(wù)端:

Socket s = new Socket();

SocketAddress server_addr=new InetSocketAddress“( 192.168.1.2”,5000);

s.connect(server_addr); 或者直接使用Socket 的構(gòu)造方法連接服務(wù)端,例如:

Socket s = new Socket(host_name,port);

從Socket類的源碼可知,該構(gòu)造方法在執(zhí)行時會自動調(diào)用connect()方法連接服務(wù)端。

客戶端在開始執(zhí)行connect()方法時,首先觸發(fā)TCP的第一次握手。如果此時服務(wù)端未啟動,或者服務(wù)端的連接隊列滿了,那么connect()方法會拋出Socket異常,提示“異常信息:Connection refused: con?nec“t 的錯誤。如果服務(wù)端正常響應(yīng),接下來會進行第二次及第三次的握手,當三次握手成功時則connect() 方法會正常返回。

3 三次握手與程序之間的關(guān)系

基于TCP協(xié)議的Java Socket程序通信的過程可以通過三個層面進行解析,如圖2所示應(yīng)用程序(Cli?ent與Server) 、Socket、操作系統(tǒng)(OS) 之間的關(guān)系。三次握手在操作系統(tǒng)層面進行,客戶端與服務(wù)端之間通過操作系統(tǒng)提供Socket API 接口完成通信連接。

1) 服務(wù)端創(chuàng)建ServerSocket對象,調(diào)用bind()綁定和監(jiān)聽端口,并創(chuàng)建一個先進先出的accept隊列;

2) 客戶端創(chuàng)建Socket對象后,通過調(diào)用其connect()方法觸發(fā)了三次握手。連接成功后,系統(tǒng)將該連接放入accept隊列。客戶端同時通過這個Socket創(chuàng)建后續(xù)與服務(wù)器通信的輸入輸出流(in、out) ;

3) 服務(wù)端調(diào)用accept()方法監(jiān)聽accept隊列是否成功連接。如果有,則取出并返回一個與對應(yīng)客戶端通信的Socket對象,并創(chuàng)建與該客戶端通信的輸入輸出流(in、out) ;

4) 在客戶端調(diào)用connect()方法成功返回后,如果服務(wù)端并沒有執(zhí)行accept()方法將這個客戶端的請求從accept隊列中取出處理,那么客戶端并不能真正地和服務(wù)端進行應(yīng)用層面上的通信。但是,客戶端已經(jīng)可以通過Socket建立輸入輸出流,并開始向服務(wù)端發(fā)送數(shù)據(jù),而服務(wù)端操作系統(tǒng)也會在TCP協(xié)議層面回復(fù)ACK包,并將數(shù)據(jù)保存在指定的緩沖區(qū)中,等待服務(wù)端程序的后期處理。

因此,三次握手與accept()方法并無直接關(guān)系。通過模擬實驗可以驗證,在未執(zhí)行accept()方法的情況下,已經(jīng)完成三次握手,如圖3所示。當accept隊列已滿時,客戶端的第一次握手請求(SYN) 后,會收到RST 包,表示重置連接,即該連接請求被服務(wù)端面拒絕,接著客戶端會連續(xù)嘗試發(fā)送SYN包,如果仍是收到RST 包,則結(jié)束連接請求,如圖4所示。只要完成了三次握手,客戶端便可以向服務(wù)端發(fā)送數(shù)據(jù),并且這些數(shù)據(jù)會在服務(wù)端的操作系統(tǒng)層面被接收并存儲在臨時空間。

4 Accept 方法處理要點分析

從服務(wù)端資源的安全使用方面考慮,服務(wù)端程序需要設(shè)定合適的最大連接數(shù)。然后,一旦設(shè)定了最大連接數(shù),如果程序沒有及時調(diào)用accept方法對取出ac?cept隊列的請求進行處理,則會帶來如下兩個問題。

1) 如果在短時間內(nèi)有較多的客戶端發(fā)起連接請求,而服務(wù)端不能夠及時地將請求從accept隊列取出進行處理,accept隊列很快會溢出,致使其他客戶端的連接都會被拒絕;

2) 客戶端一旦完成了三次握手,則可以通過Socket創(chuàng)建輸出流發(fā)送數(shù)據(jù)給服務(wù)端,如果服務(wù)端程序不及時處理,客戶端可能因為沒有及時得到回復(fù)而進入異常狀態(tài),同時服務(wù)端相應(yīng)的緩存會被大量占用。

因此,程序中如何調(diào)用accept()方法顯得非常重要。在單線程程序中,當服務(wù)器調(diào)用accept()方法接收到第一個客戶請求時,便創(chuàng)建輸入輸出流,開始與客戶端進行通信[4]。在通信結(jié)束前,不會再次調(diào)用accept()方法接收其他客戶的連接請求,而越來越多的未被接收的連接請求就會占滿整個accept隊列。解決這個問題的方式有兩種,一種是應(yīng)用非阻塞I/O技術(shù),另一種是應(yīng)用多線程技術(shù)。由于非阻塞I/O技術(shù)比較復(fù)雜,這里不展開分析。

多線程技術(shù)可以實現(xiàn)分開執(zhí)行不同的任務(wù)或者分段執(zhí)行程序代碼,從而顯著提高程序的運行效率[5]。應(yīng)用多線程解決問題的關(guān)鍵在于將接收請求與處理請求分離成兩個任務(wù)。服務(wù)端程序的主線程用于執(zhí)行接收請求任務(wù),循環(huán)地調(diào)用accept()方法,每當ac?cept()成功返回相應(yīng)Socket對象時,創(chuàng)建一個新的線程(子線程)并傳遞Socket對象,啟動這個新線程。代碼如下:

while (true){

Socket clientSocket = listenSocket.accept();

Thread t = new ClientThread(clientSocket);

t.start();

其中,ClientThread 類為子線程類(class Client?Thread extends Thread)。服務(wù)端主線程通過調(diào)用Cli?entThread類的構(gòu)造方法創(chuàng)建子線程,并調(diào)用start()方法啟動子線程用于執(zhí)行與客戶端通信的任務(wù)。這樣,主線程啟動子線程后便可以快速地返回并進入下一次的循環(huán),繼續(xù)調(diào)用accept()方法接收accept隊列中下一個客戶端的請求。在這個子線程中,通過傳遞的Socket對象創(chuàng)建通信的輸入輸出流,開始與客戶端進行數(shù)據(jù)通信。

應(yīng)用多線程響應(yīng)客戶端請求時,應(yīng)考慮服務(wù)器的資源狀況。由于服務(wù)端可以快速地處理accept隊列中的請求,將會產(chǎn)生大量的子線程用于各個客戶端的通信。如果不做任何控制,過多的子線程也有可能影響系統(tǒng)的性能。因此,最好是應(yīng)用線程池技術(shù)對這些子線程進行管理。

5 結(jié)束語

文章從應(yīng)用程序、Socket和操作系統(tǒng)三個層面分析Java Socket程序,可以看出,TCP三次握手是由程序通過調(diào)用操作系統(tǒng)的API接口,并在操作系統(tǒng)內(nèi)核層面完成的。三次握手是在服務(wù)端調(diào)用bind()方法后,由客戶端調(diào)用connect()方法觸發(fā)完成,服務(wù)端的ac?cept()方法只是用于處理已完成的連接請求,并不參與三次握手的過程。但是,如果服務(wù)端在與客戶端連接成功后,沒有及時處理accept隊列,也會影響新的客戶端的請求,致使三次握手失敗。

主站蜘蛛池模板: 久久夜色精品国产嚕嚕亚洲av| 一本色道久久88亚洲综合| 婷婷色丁香综合激情| 亚洲一区无码在线| 欧美视频免费一区二区三区| 中字无码av在线电影| 真实国产乱子伦高清| 久草中文网| 成人免费视频一区二区三区| 国产91丝袜在线播放动漫| 天天摸夜夜操| 国产亚洲精品自在久久不卡 | 国产午夜精品一区二区三| 亚洲高清免费在线观看| 99中文字幕亚洲一区二区| 成人亚洲国产| 中文成人在线| 亚洲AⅤ无码国产精品| 亚洲欧美日韩综合二区三区| 亚洲不卡影院| 91小视频在线| 欧美成人午夜影院| 日本国产在线| 欧美日韩一区二区在线播放 | 黄色成年视频| 国产色图在线观看| 中文字幕在线视频免费| 无码aaa视频| 精品国产污污免费网站| 亚洲经典在线中文字幕| 亚洲一级无毛片无码在线免费视频 | 精品无码一区二区三区在线视频| 九九热精品在线视频| 91精品国产福利| 毛片网站在线播放| 亚洲成人在线免费| 亚洲精品福利视频| 99精品福利视频| 欧美日韩91| 亚洲美女一区| 超碰精品无码一区二区| www.99在线观看| 精品成人免费自拍视频| 日韩毛片基地| 欧美yw精品日本国产精品| 久久久久亚洲av成人网人人软件| 国产成年女人特黄特色毛片免 | 亚洲欧美综合另类图片小说区| 亚洲香蕉久久| 青青草原国产| 国产v欧美v日韩v综合精品| 欧美日韩资源| 综合色区亚洲熟妇在线| 国产精品播放| 日韩久久精品无码aV| 92精品国产自产在线观看| 久久久精品国产亚洲AV日韩| 日本亚洲欧美在线| 国产成人精品第一区二区| 无码高清专区| 亚洲美女高潮久久久久久久| 国产精品无码制服丝袜| 成年人国产网站| 免费毛片视频| 五月天综合婷婷| 91国内外精品自在线播放| 四虎永久在线精品国产免费| 欧美激情视频二区| 一级毛片视频免费| 亚洲欧美极品| 欧美在线天堂| 亚洲国产欧美国产综合久久| 99热这里只有精品2| 亚洲一区二区三区国产精华液| 久久精品国产精品国产一区| 国产成人午夜福利免费无码r| 亚洲日韩国产精品综合在线观看 | 亚洲国产黄色| 久久无码av三级| 国产在线啪| 九九热这里只有国产精品| 国产SUV精品一区二区6|