楠木軒

Socket通信基本原理和長短連接

由 華愛利 發佈於 科技

Socket 是網絡上兩個程序間雙向交流連接的一個端點(類似於打電話時的兩台手機),基於TCP/IP協議,穩定有序。

A socket isone endpointof a two-way communication link between two programs running on the network. A socket is bound to a port number so that the TCP layer can identify the application that data is destined to be sent to.

An endpoint is a combination of an IP address and a port number. Every TCP connection can be uniquely identified by its two endpoints. That way you can have multiple connections between your host and the server.

套接字Socket=(IP地址:端口號),套接字的表示方法是點分十進制的lP地址後面寫上端口號,中間用冒號或逗號隔開。每一個傳輸層連接唯一地被通信兩端的兩個端點(即兩個套接字)所確定。例如:如果IP地址是192.168.56.103,而端口號是23,那麼得到套接字就是(192.168.56.103:23)。

首先Socket 通信是基於TCP/IP 網絡層上的一種傳送方式,我們通常把TCP和UDP稱為傳輸層。

Socket是基於應用服務與TCP/IP通信之間的一個抽象,它將TCP/IP協議裏面複雜的通信邏輯進行分裝,對用户來説,只要通過一組簡單的API就可以實現網絡的連接。

首先,服務端初始化ServerSocket,然後對指定的端口進行綁定,接着對端口及進行監聽,通過調用accept方法阻塞,此時,如果客户端有一個socket連接到服務端,那麼服務端通過監聽和accept方法可以與客户端進行連接。

要通過互聯網進行通信,至少需要一對套接字,其中一個運行於客户端,我們稱之為 Client Socket,另一個運行於服務器端,我們稱之為 Server Socket。

根據連接啓動的方式以及本地套接字要連接的目標,套接字之間的連接過程可以分為三個步驟:

1. 服務器監聽

所謂服務器監聽,是指服務器端套接字並不定位具體的客户端套接字,而是處於等待連接的狀態,實時監控網絡狀態。

2. 客户端請求

所調客户端請求,是指由客户端的套接字提出連接請求,要連接的目標是服務器端的套接字。為此,客户端的套接字必須首先描述它要連接的服務器的套接字,指出服務器端套接字的地址和端口號,然後就向服務器端接字提出連接請求。

3. 連接確認

所謂連接確認,是指當服務器端套接字監聽到或者説接收到客户端套接字的連接請求,就會響應客户端套接字的請求,建立一個新的線程,並把服務器端套接字的描述發送給客户端。一旦客户端確認了此描述,連接就建立好了。而服務器端套接字繼續處於監聽狀態,接收其他客户端套接字的連接請求。

1. 長連接

指在一個連接上可以連續發送多個數據包,在連接保持期間,如果沒有數據包發送,需要雙方發鏈路檢測包。整個通訊過程,客户端和服務端只用一個Socket對象,長期保持Socket的連接。

長連接過程:連接→數據傳輸→保持連接(心跳)→數據傳輸→保持連接(心跳)→……→關閉連接。

這就要求長連接在沒有數據通信時,定時發送數據包(心跳),以維持連接狀態。

2. 短連接

短連接服務是每次請求都建立鏈接,交互完之後關閉鏈接。

其實區分長、短連接就是:整個客户和服務端的通訊過程是利用一個Socket還是多個Socket進行的。

3. 長連接與短連接的比較

長連接多用於操作頻繁,點對點的通訊,而且連接數不能太多情況。每個TCP連接都需要三步握手,這需要時間。如果每個操作都是短連接,再操作的話那麼處理速度會降低很多,所以每個操作完後都不斷開,下次處理時直接發送數據包就OK了,不用建立TCP連接。例如:數據庫的連接用長連接,如果用短連接頻繁的通信會造成Socket錯誤,而且頻繁的Socket 創建也是對資源的浪費。

Socket是針對應用層與TCP/IP數據傳輸協議封裝的一套方案,那麼它的底層也是通過TCP/IP或則UDP通信的,所以説Socket本身並不是一套通信協議,而是一套接口的封裝。

而TCP/IP協議組裏面的應用層包括FTP、HTTP、TELNET、SMTP、DNS等協議,我們知道,http1.0是短連接,http1.1是長連接。我們在打開http通信協議裏面在Request Headers中可以看到:Connection: keep-alive。

對應的Response Headers也可以看到。

它是幹什麼的?

它就是表示長連接,但是它並不是一直保持的連接,有一個時間段(Connection Timeout)。

如果我們想一直保持這個連接怎麼辦?

那就是在指定的時間內讓客户端和服務端進行一個請求,請求可以是服務端發起,也可以是客户端發起,通常我們是在客户端不定時的發送一個字節數據給服務端,這個就是我們稱之為心跳包。