1. 程式人生 > >為什麼有監聽socket和連線socket,為什麼產生兩個socket

為什麼有監聽socket和連線socket,為什麼產生兩個socket

為什麼有監聽socket和連線socket,為什麼產生兩個socket

先看一半的socket建立連線的雙方的過程:

客戶端:

socket()---->創建出 active_socket_fd (client_socket_fd)

bind()--->把active_socket_fdip,port繫結起來

connect()--->client_socket_fd 主動請求服務端的 listen_socket_fd

read()/write()---->讀/寫 socket io

close()---->關閉socket_fd

服務端:

socket()

---->創建出 active_socket_fd

bind()--->把active_socket_fd與ip,port繫結起來

listen()---->active_socket_fd--> listen_socket_fd 等待客戶端的client_socket_fd來請求連線

accept()---->listen_socket_fd-->connec_socket_fd 把監聽socket轉變為連線socket,用於建立連線購的讀寫資料

read()/write()---->讀/寫 socket io

close()---->關閉socket_fd

linux核心, socket函式建立的套接字是主動套接字

一開始socket函式, 不管在客戶端還是在服務端, 建立的都是主動socket, 但是在服務端經過listen(), 後把其轉變為listen_socket_fd(被動監聽socket),
經過accept()後轉變為connect_socket_fd(已連線socket).

在轉變為connect_socket_fd之前, 都是同一個socket, 只不過是socket的狀態改變了, 但是服務端經過accept()後返回的socket是新的socket, 用於連線後的read()/write()

為什麼服務端這麼特殊, 需要兩種狀態的socket, 並且在這個過程中產生兩個socket?

需要兩種狀態的socket?

對於前者, 這個比較好理解, 因為是現在的網路程式中是C/S結構的, 一般是客戶端主動向服務端請求建立連線. 這個過程中, 主要涉及到兩個狀態, 一個是主動, 一個是被動的. 因此, 客戶端的socket只用於主動向服務端的socket請求建立連線, 服務端的socket一直被動的等待客戶端的請求連線就ok了. 所以這就解答了為什麼需要兩種狀態的socket, 只有一方是主動, 另一方是被動, 才能否完成上面的過程. 如果雙方都是主動, 或者被動, 就完成不了上面的過程了.

1.產生兩個socket?

等等, 上面好像沒有說到為什麼服務端需要產生兩個socket(監聽socket和已連線socket)

這個我認為是, 監聽socket,是伺服器作為客戶端連線請求的一個對端,只需建立一次能夠讓客戶端請求到有這個端點就ok,所以監聽socket(listen_socket_fd)存在於伺服器的整個生命週期, 不需要每個連線都建立一個新的監聽socket出來, 沒必要呢。已連線socket(connect_socket_fd)是客戶端與伺服器之間已經建立起來了的連線的一個端點,伺服器每次接受連線請求時都會建立一個新已連線socket,它的生命週期只是客戶端請求服務端的時間範圍內。

2.為什麼不只使用一個listen_socket_fd完成從建立監聽socket(listen_socket_fd), 到被請求連線, 處理請求, 關閉socket的整個過程呢? 而需要用一個listen_socket_fd作為監聽客戶端請求, 然後每個連線建立一個新的connect_socket_fd來完成服務端與客戶端的"交流"?
  • 假設前者那種情況, 只用一個socket完成整個過程. 那麼這個socket就會一直被佔用, 而不能被另外的客戶端請求, 造成了服務端的效能極其低下, 如果沒有儲存後面的客戶端請求, 就會被錯過而丟棄, 因為當前的socket正在與當前一個客戶端的socket建立連線.
  • 所以從上面的情況可以得知, 在請求連線和連線後需要的socket應該不是同一個, 它們負責的工作是不一樣的. 有了listen_socket_fd和connect_socket_fd後, 就可以專門用一listen_socket_fd負責響應客戶端的請求, 每次新的connect_socket_fd專門負責當前這次連線的資料互動.

總結

為什麼需要兩種socket(監聽socket和已連線socket)已經說得明白了, 總的來說是, 是為了職責分工, 分層協作, 提高服務端效能.