現在的位置: 首頁 > 搜索技術 > 正文

面向連接和無連接的套接字有什麼區別?

2020年02月12日 搜索技術 ⁄ 共 2356字 ⁄ 字型大小 評論關閉

  流格式套接字(Stream Sockets)就是「面向連接的套接字」,它基於 TCP 協議;數據報格式套接字(Datagram Sockets)就是「無連接的套接字」,它基於 UDP 協議。

  這給大家造成一種印象,面向連接就是可靠的通信,無連接就是不可靠的通信,實際情況是這樣嗎?

  另外,不管是哪種數據傳輸方式,都得通過整個 Internet 網路的物理線路將數據傳輸過去,從這個層面理解,所有的 socket 都是有物理連接的呀,為什麼還有無連接的 socket 呢?

  本節就來給大家解開種種謎團,加深大家對數據傳輸方式的認識。

  從字面上理解,面向連接好像有一條管道,它連接發送端和接收端,數據包都通過這條管道來傳輸。當然,兩台計算機在通信之前必須先搭建好管道。

  無連接好像沒頭蒼蠅亂撞,數據包從發送端到接收端並沒有固定的線路,愛怎麼走就怎麼走,只要能到達就行。每個數據包都比較自私,不和別人分享自己的線路,但是,大家最終都能殊途同歸,到達接收端。

  這樣理解沒錯,但是我相信這還不夠深入,大家還是感覺雲里霧裡,沒有看到本質。

  假設 H1 要發送若干個數據包給 H6,那麼有多條路徑可以選擇,比如:

  路徑①:H1 --> A --> C --> E --> H6

  路徑②:H1 --> A --> B --> E --> H6

  路徑③:H1 --> A --> B --> D --> E --> H6

  路徑④:H1 --> A --> B --> C --> E --> H6

  路徑⑤:H1 --> A --> C --> B --> D --> E --> H6

  數據包的傳輸路徑是路由器根據演算法來計算出來的,演算法會考慮很多因素,比如網路的擁堵狀況、下一個路由器是否忙碌等。

  無連接的套接字

  對於無連接的套接字,每個數據包可以選擇不同的路徑,比如第一個數據包選擇路徑④,第二個數據包選擇路徑①,第三個數據包選擇路徑②……當然,它們也可以選擇相同的路徑,那也只不過是巧合而已。

  每個數據包之間都是獨立的,各走各的路,誰也不影響誰,除了迷路的或者發生意外的數據包,最後都能到達 H6。但是,到達的順序是不確定的,比如:

  第一個數據包選擇了一條比較長的路徑(比如路徑⑤),第三個數據包選擇了一條比較短的路徑(比如路徑①),雖然第一個數據包很早就出發了,但是走的路比較遠,最終還是晚於第三個數據包達到。

  第一個數據包選擇了一條比較短的路徑(比如路徑①),第三個數據包選擇了一條比較長的路徑(比如路徑⑤),按理說第一個數據包應該先到達,但是非常不幸,第一個數據包走的路比較擁堵,這條路上的數據量非常大,路由器處理得很慢,所以它還是晚於第三個數據包達到了。

  還有一些意外情況會發生,比如:

  第一個數據包選擇了路徑①,但是路由器C突然斷電了,那它就到不了 H6 了。

  第三個數據包選擇了路徑②,雖然路不遠,但是太擁堵,以至於它等待的時間太長,路由器把它丟棄了。

  總之,對於無連接的套接字,數據包在傳輸過程中會發生各種不測,也會發生各種奇蹟。H1 只負責把數據包發出,至於它什麼時候到達,先到達還是後到達,有沒有成功到達,H1 都不管了;H6 也沒有選擇的權利,只能被動接收,收到什麼算什麼,愛用不用。

  無連接套接字遵循的是「盡最大努力交付」的原則,就是儘力而為,實在做不到了也沒辦法。無連接套接字提供的沒有質量保證的服務。

  面向連接的套接字

  面向連接的套接字在正式通信之前要先確定一條路徑,沒有特殊情況的話,以後就固定地使用這條路徑來傳遞數據包了。當然,路徑被破壞的話,比如某個路由器斷電了,那麼會重新建立路徑。

  這條路徑是由路由器維護的,路徑上的所有路由器都要存儲該路徑的信息(實際上只需要存儲上游和下游的兩個路由器的位置就行),所以路由器是有開銷的。

  H1 和 H6 通信完畢後,要斷開連接,銷毀路徑,這個時候路由器也會把之前存儲的路徑信息擦除。

  在很多網路通信教程中,這條預先建立好的路徑被稱為「虛電路」,就是一條虛擬的通信電路。

  為了保證數據包準確、順序地到達,發送端在發送數據包以後,必須得到接收端的確認才發送下一個數據包;如果數據包發出去了,一段時間以後仍然沒有得到接收端的回應,那麼發送端會重新再發送一次,直到得到接收端的回應。這樣一來,發送端發送的所有數據包都能到達接收端,並且是按照順序到達的。

  發送端發送一個數據包,如何得到接收端的確認呢?很簡單,為每一個數據包分配一個 ID,接收端接收到數據包以後,再給發送端返回一個數據包,告訴發送端我接收到了 ID 為 xxx 的數據包。

  面向連接的套接字會比無連接的套接字多出很多數據包,因為發送端每發送一個數據包,接收端就會返回一個數據包。此外,建立連接和斷開連接的過程也會傳遞很多數據包。

  不但是數量多了,每個數據包也變大了:除了源埠和目的埠,面向連接的套接字還包括序號、確認信號、數據偏移、控制標誌(通常說的 URG、ACK、PSH、RST、SYN、FIN)、窗口、校驗和、緊急指針、選項等信息;而無連接的套接字則只包含長度和校驗和信息。

  有連接的數據包比無連接大很多,這意味著更大的負載和更大的帶寬。許多即時聊天軟體採用 UDP 協議(無連接套接字),與此有莫大的關係。

  總結

  兩種套接字各有優缺點:

  無連接套接字傳輸效率高,但是不可靠,有丟失數據包、搗亂數據的風險;

  有連接套接字非常可靠,萬無一失,但是傳輸效率低,耗費資源多。

  兩種套接字的特點決定了它們的應用場景,有些服務對可靠性要求比較高,必須數據包能夠完整無誤地送達,那就得選擇有連接的套接字(TCP 服務),比如 HTTP、FTP 等;而另一些服務,並不需要那麼高的可靠性,效率和實時才是它們所關心的,那就可以選擇無連接的套接字(UDP 服務),比如 DNS、即時聊天工具等。

抱歉!評論已關閉.