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

為什麽有監聽socket和連接socket,為什麽產生兩個socket

中產 能夠 新的 被占用 con 提高 tro 客戶端 分層

為什麽有監聽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)已經說得明白了, 總的來說是, 是為了職責分工, 分層協作, 提高服務端性能.

為什麽有監聽socket和連接socket,為什麽產生兩個socket