計算機網路再次整理————tcp例子第二前奏[四]

敖毛毛發表於2022-02-04

前言

前文我們介紹了網路協議的各層,同時也介紹了一下我們在編寫程式碼時候的服務端的accept、bind、listen、connect、send做了什麼。

可以說是從巨集觀的角度,或者程式碼開發的角度來說的,在此我覺得還不夠具體。

同樣我想解釋一下為什麼我說服務端listen之後,客戶端已經可以進行tcp連線了,同樣可以傳送訊息了。

正文

首先我們的tcp連線網圖:

前提,這個時候服務端只是listen了,並沒有accept。且客戶端呼叫了connect,同時send 了hello word了。

第一個包:

客戶端發起tcp連線。

上面可以看到seq 為0,同樣有0x002 SYN 標誌。

第二個包:

這是伺服器端給客戶端的.

說明此時服務端是認可了客戶端的請求的,並且呢,開始進行了確認操作。

第三個包:

這是客戶端發出的,3次握手已經完成了,說明已經連線上了。

然後就是要確認之後listen 之後是否可以傳送訊息。

第四個包:

客戶端已經向服務端發起了訊息。

可以看到資料是:68656c6c6f2073657276696365

大家可以用utf8 16進位制進行解碼看下解密出來的是啥。

第五個包:

服務端的確認包。說明服務端確認收到了資料的。

其實這些連線和收包前文提及了,其實都是作業系統幫助我們做了。

那麼為什麼有些書本要寫,accept 之後才是連線呢?

這是因為相當我們的應用程式而言的,accept之後,我們才能知道客戶端連線過來的在服務端建立的socket是多少。

這個時候服務端才知道有客戶端進行了連線了,所以認為這個時候才連線成功了。而一些書本認為服務端也不包含作業系統,僅是我們的應用程式。

這裡我用的是wireshark 進行抓包的。

本來想把四次揮手也截圖出來的,但是後面向介紹一些更具體的東西,所以往後推一推吧,這樣也不會冗餘,同時大家交流起來更加的自然。

實驗程式碼如下:
服務端:

using System.Net;
using System.Net.Sockets;

var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var ipAddress = IPAddress.Parse("127.0.0.1");
EndPoint endPoint = new IPEndPoint(ipAddress, 8888);
socket.Bind(endPoint);
socket.Listen();
Console.ReadLine();

客戶端:

using System.Net;
using System.Net.Sockets;

var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var ipAddress = IPAddress.Parse("127.0.0.1");
EndPoint endPoint = new IPEndPoint(ipAddress, 8888);
socket.Connect(endPoint);
socket.Send(System.Text.Encoding.UTF8.GetBytes("hello service"));
Console.WriteLine("傳送成功");
Console.ReadLine();

以上只是個人的整理,如有錯誤,望請指點。

相關文章