【轉】第一篇-linux中socket通信

 

轉, 原文:https://zhuanlan.zhihu.com/p/628583834

----------------

 

客戶端和服務端是如何通信的

在linux中客戶端和服務端通信的流程如圖所示:

流程分析:
服務器端先初始化Socket,然後與端口綁定(bind),對端口進行監聽(listen),調用accept阻塞,等待客戶端連接。在這時如果有個客戶端初始化一個Socket,然後連接服務器(connect),如果連接成功,這時客戶端與服務器端的連接就建立了。客戶端發送數據請求,服務器端接收請求並處理請求,然後把迴應數據發送給客戶端,客戶端讀取數據,最後關閉連接,一次交互結束。

TCP服務端通過依次調用 socket(),bind(),listen()之後,就會監聽指定的socket地址了。客戶端如果調用connect()發出一個 連接請求,服務端監聽到這個 連接請求之後,就會調用accept()函數去接受請求,這樣連接就建立好了,之後就可以進行網絡IO操作了。

連接是如何建立的

前面我們講的,客戶端調用connect()發起連接請求,服務端監聽到這個連接請求,就會調用accept()接受請求,這個流程是兩者建立連接的流程,這個連接建立的流程就是三次握手協議。

  1. 當客戶端調用connect()時,觸發了連接請求,向服務器發送了syn包,這時客戶端會進入阻塞狀態;
  2. 服務端監聽到連接請求,即收到了syn包,調用accept函數接受請求向客戶端發送syn&ack,這時服務端也會進入阻塞狀態;
  3. 客戶端收到收到服務器的syn&ack包,connect()會返回給服務端ack;
  4. 服務端收到ack之後,accept()方法會返回(即執行結束)

思考:客戶端和服務端具體socket是如何進行通信的?(我也不知道這樣描述對不對)
假設服務端已經創建一個socket,用於監聽客戶端的連接請求。現在有兩個客戶端socket A和B嘗試連接到服務端。

  1. 客戶端socket A向服務端發送連接請求
  2. 服務端使用accept函數接受客戶端socket A的連接請求,併爲其創建一個新的socket socketA,該新的socket將用於與客戶端socket A進行通信。
  3. 客戶端socket B也向服務端發送連接請求
  4. 服務端使用accept函數同樣接受客戶端socket B的連接請求,併爲其創建一個新的socket socketB,該新的socket將用於與客戶端socket B進行通信。

此時,服務端就有了兩個新的socket:socketA用於與客戶端socket A進行通信,socketB用於與客戶端socket B進行通信。這兩個socket是獨立的,互不干擾。每個socket都可以單獨處理某個客戶端的請求和數據傳輸。這樣,服務端就可以同時處理多個客戶端的請求和數據傳輸,提高了併發性能和效率。
需要注意的是,服務端通過這些socket與不同的客戶端進行通信,服務端原始的socket只用於監聽客戶端的連接請求,而不用於實際的數據傳輸,因此它可以同時處理多個客戶端的連接請求。而新創建的每個socket則對應一個獨立的客戶端,並且每個socket只能用於與對應的客戶端進行通信。
ps:這裏再囉嗦一句,服務端原始socket只用於建立連接,數據傳輸由新的socket去做。

思考:我們前面學習了客戶端和服務端如何進行通信,但是我們發現一個問題,就是那種通信方式只適用於一個客戶端和一個服務端進行通行,如果我們想多個客戶端和一個服務端通信,要怎麼做呢?這裏就引出了網絡IO通信模型


參考文章:

Linux的SOCKET編程詳解_linux socket_hguisu的博客-CSDN博客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章