java數據庫socket解說與socket與端口和IP地址到底是什麼

java數據庫socket解說與socket與端口和IP地址到底是什麼

三者從本質上來說沒有可比性, socket則是對TCP/IP協議的封裝和應用(程序員層面上)。 也可以說,TPC/IP協議是傳輸層協議,主要解決數據如何在網絡中傳輸, 而HTTP是應用層協議,主要解決如何包裝數據。 關於TCP/IP和HTTP協議的關係,網絡有一段比較容易理解的介紹: “我們在傳輸數據時,可以只使用(傳輸層)TCP/IP協議,但是那樣的話,如果沒有應用層,便無法識別數據內容。 如果想要使傳輸的數據有意義,則必須使用到應用層協議。 應用層協議有很多,比如HTTP、FTP、TELNET等,也可以自己定義應用層協議。 WEB使用HTTP協議作應用層協議,以封裝HTTP文本信息,然後使用TCP/IP做傳輸層協議將它發到網絡上。” 而我們平時說的最多的socket是什麼呢,實際上socket是對TCP/IP協議的封裝,Socket本身並不是協議,而是一個調用接口(API)。 通過Socket,我們才能使用TCP/IP協議。 實際上,Socket跟TCP/IP協議沒有必然的聯繫。 Socket編程接口在設計的時候,就希望也能適應其他的網絡協議。 所以說,Socket的出現只是使得程序員更方便地使用TCP/IP協議棧而已,是對TCP/IP協議的抽象, 從而形成了我們知道的一些最基本的函數接口,比如create、listen、connect、accept、send、read和write等等。 網絡有一段關於socket和TCP/IP協議關係的說法比較容易理解: “TCP/IP只是一個協議棧,就像操作系統的運行機制一樣,必須要具體實現,同時還要提供對外的操作接口。 這個就像操作系統會提供標準的編程接口,比如win32編程接口一樣, TCP/IP也要提供可供程序員做網絡開發所用的接口,這就是Socket編程接口。” 關於TCP/IP協議的相關只是,用博大精深來講我想也不為過,單單查一下網上關於此類只是的資料和書籍文獻的數量就知道,

他終於明白了所謂IP層就是把數據分組從一個主機跨越千山萬水搬運到另外一主機, 並且這搬運服務一點都不可靠, 丟包、重複、失序可以說是家常便飯, 怪不得說是“盡力而為”, 基本上無所作為。

髒活累活只好讓TCP來做了, 在兩個主機的應用(進程)之間通過失敗重傳來實現可靠性的傳輸。

張大胖經常感慨:這建立一個TCP連接可是相當的複雜, 我的程序得先和遠端的服務器打個招呼, 然後它再給我打個招呼確認, 我還得再給它確認下。 這還不算完, 我們的招呼中還得各自帶上各自的序號, 這將來傳輸真正的數據時用到。

具體的傳輸就更麻煩了, 什麼滑動窗口,什麼累積確認、分組緩存、流量控制, 簡直不是人做的事情。

到了斷開連接的時候, 還得考慮友好分手!

可是領導竟然讓張大胖用這個超級複雜的TCP協議來編程, 來設計一個客戶端和服務器端的通信系統。

張大胖掂量了下自己, 覺得肯定搞不定, 於是趕緊向自己的好基友,編程大神Bill求救, Bill 在電話裡說: “這很簡單啊,你去看看TCP/IP協議的RFC, 然後用C語言編程實現不就行了嗎。”

張大胖心想這等於啥也沒說, 繼續“跪求” 。 Bill 終於說:“等著吧, 我下週給你”

Socket

週一, Bill果然帶著7、8張軟盤來找張大胖了, 把軟盤的程序分別Copy到了兩個電腦裡, 一個模擬客戶端, 一個模擬服務器。 很快程序運行起來了, 兩個電腦可以通過TCP通信了。

張大胖說: “大神, 你是怎麼做到的?”

Bill說:“TCP協議的確很複雜, 我們不能要求每個程序員都去實現建立連接的3次握手, 累積確認,分組緩存, 這些應該是屬於操作系統內核的部分, 沒必要重複開發, 但是對於應用程序來講, 操作系統需要抽象出一個概念, 讓上層應用去編程。 “

“什麼概念?”

“socket”

”為啥叫socket? “

"一個比喻而已, 就像插座一樣, 一個插頭插進插座, 建立了連接。 不過我設計這個socket 可以理解為 (客戶端IP, 客戶端Port, 服務器端IP, 服務器端Port), 對了, Port就是端口, 通俗點講就是一個數字而已"

“好像不用port就可以吧, 因為我們這是兩個機器之間的通信, IP是不是就夠了?”

Bill 說:“看來你忘了, TCP是兩個進程之間的通信, 客戶端上可以有很多進程同時訪問多個服務器, 服務器上也有多個進程對外提供服務, 肯定要區分開啊”

張大胖不好意思的說: “原來端口號就是用來區分進程的, 這樣IP層發過來的數據包, 到達TCP層以後就可以分發給各個應用程序了。 ”

“對的, 這叫多路複用。 一般來說, 服務器端都是被動訪問的, 所以大家需要知道它提供服務的端口號, 要不然怎麼連接? 例如80, 443等, 就是所謂知名端口號; 而客戶端訪問服務器的時候,自己的端口號可以隨機生成一個, 只要不和別的應用衝突即可。”

java數據庫socket解說與socket與端口和IP地址到底是什麼

Socket編程

張大胖問道: “那具體怎麼使用你的Socket來編程? ”

“這要分為客戶端和服務器端,兩者不一樣, 對客戶端來講很簡單, 你需要創建一個socket, 然後向服務器發起連接, 連接上以後就可以發送,接收數據了, 你看看這段偽代碼“

java數據庫socket解說與socket與端口和IP地址到底是什麼

"恩, 抽象以後果然是不一樣, 那些煩人的細節都被隱藏了, 只剩下一些概念性的東西, 用起來很清爽, 這個clientfd 我猜就是一個像文件描述符那樣的東西吧? 打開文件就會有一個"

“對的, 很好的類比, 注意,在上面的偽碼中,沒有出現客戶端的ip和端口, 系統可以自動獲得IP, 也可以自動分配端口。 還有, 看到那個connect 函數沒有, 其實就是在和服務器發起三次握手呢。 ”

“那服務器怎麼響應?”

“服務器端要複雜一些, 你想想看, 第一, 服務器是被動的, 所以它啟動以後, 需要監聽客戶端發起的連接, 第二, 服務器要應付很多的客戶端發起連接, 所以它一定得各個socket給區分開了, 要不就亂了套了, 偽代碼是這個樣子的:”

java數據庫socket解說與socket與端口和IP地址到底是什麼

張大胖說: “果然是複雜多了, listenfd ,從名稱看就是為了要監聽而創建的socket描述符吧, bind 是幹嘛? 嗯, 我猜是為了聲明說我要佔用這個端口了啊, 你們都別用了, listen函數才是真正開始監聽了。

慢著,我賽, 接下來是個死循環啊, 啊對對,服務器端一直提供服務, 永不停歇。 可是這個accept是幹嘛, 為什麼使用了listenfd , 然後返回了一個新的connfd ???”

Bill滿意的說: “不錯,思考就有進步, 可是你忘了我剛說的東西了, 服務器要區分開各個客戶端, 怎麼區分呢? 那只有用一個新的socket來表示嘍, 你看後面的操作都是基於connfd 來做的。 還有這個accept 相當於和客戶端的connect 一起完成了TCP的三次握手 ! 至於之前的listenfd , 它只起到一個大門的作用了, 意思是說,歡迎敲門, 進門之後我將為你生成一個獨一無二的socket描述符! ”

java數據庫socket解說與socket與端口和IP地址到底是什麼

“有道理, 大神果然是大神, 考慮的非常全面啊, 不過似乎有個漏洞,你一開始說socket指的是 (IP, Port), 現在你已經有了一個listenfd 的socket, 端口是80 然後每次客戶端發起連接還要創建新的connfd, 因為80端口已經被佔用,難道服務器端會為每個連接都創建新的端口嗎?”

"這是個好問題啊" Bill 說 “其實新創建的connfd 並沒有使用新的端口號,也是用的80, 可以這麼理解,這個socket描述符指向一個數據結構, 例如 listenfd 指向的結構是這樣的:”

java數據庫socket解說與socket與端口和IP地址到底是什麼

“而一旦accept 新的連接, 新的connfd 就會生成, 像下面的表格, 就生成了兩個connfd , 它們倆服務器端的ip和port都是想同的, 但是客戶端的IP和Port是不同的, 自然就可以區分開來了”

java數據庫socket解說與socket與端口和IP地址到底是什麼

張大胖說:“唉, 這底層做了這麼多工作啊, 看來socket 必須得通過(客戶端IP, 客戶端Port, 服務器端IP, 服務器端Port) 來確定”

“其實這個四元組還不太準確, 因為咱們說了半天,都是TCP協議的socket, 因為你們領導只要你實現這一個, 你看過UDP沒有? 就是那個無連接的運輸層協議, 也有socket, 所以更準確的定義的話,還得加上協議這一項, 變成五元組(協議, 客戶端IP, 客戶端Port, 服務器端IP, 服務器端Port)

“大神,咱們什麼時候講講UDP的socket ? ”

"下次再說吧!"

題外話: 文中提到的Bill 是向 Bill Joy致敬, 這是一個天才程序員,主要工作包括BSD Unix操作系統, 實現TCP/IP協議棧, vi 編輯器,c shell , NFC, SPARC處理器,jini等。

當年DARPA(美國國防部先進研究項目局)和一個叫做BBN的公司簽署了一個合同,要把TCP/IP協議加入到Berkeley Unix當中, 當研究生Bill Joy 看到BBN寫的TCP/IP實現時, 覺得非常差勁,拒絕把它加入內核, 後來乾脆捲起袖子自己實現了一個高性能的TCP/IP棧, 這個協議棧至今是互聯網的基石。

別人問他是怎麼實現這麼複雜的軟件的, 這位大神說: “很簡單啊, 你只需要看看協議, 然後把代碼寫出來就行了”

java數據庫socket解說與socket與端口和IP地址到底是什麼

java數據庫socket解說與socket與端口和IP地址到底是什麼

私我 1 拿走 乾貨

相關推薦

推薦中...