新聞中心
?前言
不明白 Socket 是什么的主要原因其實(shí)就是沒(méi)有實(shí)際的網(wǎng)絡(luò)編程經(jīng)驗(yàn),就沒(méi)有在代碼里用過(guò) Socket,背來(lái)背去還是腦袋一片漿糊,很正常,看完這篇文章肯定就清楚了(狗頭)

創(chuàng)新互聯(lián)建站專(zhuān)注于潤(rùn)州企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站建設(shè),商城網(wǎng)站建設(shè)。潤(rùn)州網(wǎng)站建設(shè)公司,為潤(rùn)州等地區(qū)提供建站服務(wù)。全流程按需網(wǎng)站開(kāi)發(fā),專(zhuān)業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)建站專(zhuān)業(yè)和態(tài)度為您提供的服務(wù)
TCP 四元組
要說(shuō) Socket,那當(dāng)然不能繞過(guò) TCP 了,各位不妨先來(lái)思考下如何確定一個(gè) TCP 連接?
以小黑和小白為例,他們分別位于不同的小區(qū),小黑找小白玩,需要知道小白的小區(qū)和門(mén)牌號(hào),也就是說(shuō),小區(qū) + 門(mén)牌號(hào)就是小白家的入口,知道了這個(gè)入口,小黑就能找到小白。反之也是同樣的。
小區(qū)類(lèi)比于 IP 地址,門(mén)牌號(hào)類(lèi)比于端口號(hào),IP 地址 + 端口號(hào)(小區(qū) + 門(mén)牌號(hào)) 就能唯一確定一個(gè)程序。光有小區(qū)不行,光有門(mén)牌號(hào)也不行,所以這就是為什么說(shuō)網(wǎng)絡(luò)層負(fù)責(zé)建立主機(jī)到主機(jī)的通信(IP 地址),傳輸層負(fù)責(zé)建立端口到端口的通信(端口號(hào))了。
這個(gè)很好記憶,你上線(xiàn)一個(gè)網(wǎng)站的時(shí)候,如果沒(méi)有綁定域名的話(huà),那么就只能通過(guò) IP 地址 + 端口號(hào)(默認(rèn)是 80,瀏覽器上不顯示)訪(fǎng)問(wèn)。
總結(jié)下就是,TCP 四元組可以唯一的確定一個(gè)連接,四元組包括如下:
- 目的 IP 地址
- 目的端口
- 源 IP 地址
- 源端口
其中:
- IP 地址(源地址和目的地址,32位)是在 IP 頭部中
- 端口號(hào)(源端口和目的端口,16位)是在 TCP 頭部中
Socket
掌握了四元組這個(gè)基本概念,我們?cè)賮?lái)解釋 Socket。
上文說(shuō)過(guò),小區(qū) + 門(mén)牌號(hào)是住宅的入口,IP 地址 + 端口號(hào)是一個(gè)程序的入口,這個(gè)入口就是 Socket,那么服務(wù)端和客戶(hù)端之間想要進(jìn)行通信,只要互相暴露出自己的入口(Socket),就能夠找到彼此了。
更嚴(yán)謹(jǐn)來(lái)說(shuō),Socket 封裝了基本的通信功能,是 TCP/IP 協(xié)議的基本操作單元。
以 Java 中的 Socket? 類(lèi)為例,服務(wù)端和客戶(hù)端首先都需要調(diào)用構(gòu)造函數(shù)創(chuàng)建 Socket 暴露自己的入口(綁定 IP 地址和端口,也可以調(diào)用 bind 方法進(jìn)行綁定)
光暴露了入口還不行,你還得豎起耳朵聽(tīng),不然別人來(lái)敲門(mén)你聽(tīng)不見(jiàn)那也沒(méi)法通信啊,所以接下來(lái)服務(wù)端調(diào)用 accept() 方法,該方法將一直等待,直到客戶(hù)端請(qǐng)求服務(wù)端的入口,再就是 TCP 三次握手建立連接的過(guò)程了。
服務(wù)端 Socket 創(chuàng)建一般使用 ServerSocket 類(lèi),該類(lèi)提供了非常重要的 accept(建立連接) :
那客戶(hù)端是如何請(qǐng)求服務(wù)端的入口的呢?也就是是如何發(fā)起連接的呢,客戶(hù)端在創(chuàng)建好 Socket 后,調(diào)用 connect(host, port) 函數(shù)發(fā)起連接,該函數(shù)需要指明服務(wù)端的 IP 地址和端口號(hào)。
所以說(shuō),TCP 三次握手其實(shí)是發(fā)生在客戶(hù)端 connect? 和服務(wù)端 accept? 兩個(gè)函數(shù)之間。握手完了就可以通過(guò) read()? 和 write() 來(lái)通信啦。這里需要重點(diǎn)注意的是:監(jiān)聽(tīng)的 Socket 和真正用來(lái)傳數(shù)據(jù)的 Socket 是兩個(gè)不同的 Socket:
- 一個(gè)是 監(jiān)聽(tīng) Socket;
- 一個(gè)是 已連接 Socket;
看下上述的 ServerSocket.accept? 方法就明白了,accept會(huì)返回一個(gè) Socket 對(duì)象,后續(xù)服務(wù)端和客戶(hù)端之間的數(shù)據(jù)傳輸都用這個(gè) Socket:
事實(shí)上,在三次握手的過(guò)程中,內(nèi)核(Kernel)為每個(gè)連接都維護(hù)了兩個(gè)隊(duì)列:
- TCP 半連接隊(duì)列:這個(gè)隊(duì)列存儲(chǔ)沒(méi)有完成三次握手的 Socket,此時(shí)服務(wù)端處于 syn_rcvd 的狀態(tài);
- TCP 全連接隊(duì)列:這個(gè)隊(duì)列存儲(chǔ)已經(jīng)完成了三次握手的 Socket,此時(shí)服務(wù)端處于 established 狀態(tài);
當(dāng) TCP 全連接隊(duì)列不為空后,服務(wù)端的 accept() 函數(shù),就會(huì)從內(nèi)核中的 TCP 全連接隊(duì)列里拿出一個(gè)已經(jīng)完成連接的 Socket 并返回,用于后續(xù)服務(wù)端和客戶(hù)端的通信。
總結(jié)
綜上, 基于 TCP 協(xié)議的 Socket 調(diào)用過(guò)程就結(jié)束了,下面由貼心助理 ChatGPT 總結(jié)下:
以下全是 ChatGPT 生成的結(jié)果,沒(méi)有一個(gè)字是我寫(xiě)的(),雖然是我引導(dǎo)了很多輪的結(jié)果,但是輸入合適的 Promt 并配合上下文 ChatGPT 基本能輸出 90% 想要的內(nèi)容,確實(shí)太強(qiáng)了
文字解釋?zhuān)?/p>
代碼示例:
客戶(hù)端代碼示例
服務(wù)器端代碼示例
由于我懶得畫(huà)圖,所以決定再讓 ChatGPT 幫我生成下,雖然結(jié)果不是很行,不過(guò)還是能看,不用我費(fèi)勁畫(huà)了,舒服!
在上面的流程圖中,Socket 客戶(hù)端和服務(wù)端之間的通信過(guò)程如下:
- 客戶(hù)端創(chuàng)建一個(gè) Socket 對(duì)象,指定服務(wù)端的 IP 地址和端口號(hào),然后調(diào)用 connect() 方法發(fā)起連接請(qǐng)求。
- 服務(wù)端創(chuàng)建一個(gè) ServerSocket 對(duì)象,并指定端口號(hào),然后調(diào)用 accept() 方法等待客戶(hù)端連接請(qǐng)求。
- 當(dāng)客戶(hù)端的連接請(qǐng)求到達(dá)服務(wù)端,服務(wù)端的 accept() 方法會(huì)返回一個(gè)新的 Socket 對(duì)象,該 Socket 對(duì)象代表了客戶(hù)端和服務(wù)端之間的通信連接。
- 客戶(hù)端可以通過(guò)該 Socket 對(duì)象的 getOutputStream()? 方法獲取輸出流對(duì)象,用于向服務(wù)端發(fā)送數(shù)據(jù);也可以通過(guò)該 Socket 對(duì)象的 getInputStream() 方法獲取輸入流對(duì)象,用于接收服務(wù)端發(fā)送的數(shù)據(jù)。
- 服務(wù)端可以通過(guò)該 Socket 對(duì)象的 getOutputStream()? 方法獲取輸出流對(duì)象,用于向客戶(hù)端發(fā)送數(shù)據(jù);也可以通過(guò)該 Socket 對(duì)象的 getInputStream() 方法獲取輸入流對(duì)象,用于接收客戶(hù)端發(fā)送的數(shù)據(jù)。
- 客戶(hù)端和服務(wù)端可以通過(guò)各自的輸出流和輸入流進(jìn)行數(shù)據(jù)的讀寫(xiě)操作。
- 當(dāng)通信完成后,客戶(hù)端和服務(wù)端都需要調(diào)用該 Socket 對(duì)象的 close() 方法關(guān)閉連接。
文章題目:背了一年的計(jì)網(wǎng)八股,還不知道什么是Socket?
分享地址:http://www.5511xx.com/article/djoipph.html


咨詢(xún)
建站咨詢(xún)
