網路程式設計之理論篇

2021-09-11 12:43:37 字數 4169 閱讀 5499

網路通訊作為網際網路的技術支援,已被廣泛應用在軟體開發中,無論是web,服務端,客戶端還是桌面應用,都是必須掌握的一門技術。

在軟體開發層面實現遠端資料交換的程式設計技術。

複製**

要熟悉網路程式設計,首先需要學習網路協議的相關知識。

什麼網路協議呢?網路協議是為網路中進行資料交換定義的規則,以實現按此規範進行傳輸資料,就可在整個網際網路中進行資料交換的目標。所以說網路協議是網路通訊的基礎。

網路協議中其中最著名就是tcp/ip協議族。tcp/ip協議族通常被認為是乙個四層的協議系統。從上到下依次為:

從tcp/ip協議族各層次的職責來看,網路資料的傳遞是從上到下依次傳遞。以http協議為為例,具體的資料傳輸過程如圖所示:

簡單來說,資料從本機上傳到網路之前,會在tcp/ip協議族的每一層新增協議首部,到達目標主機後,目標主機再進行分解,從而獲取需要的資料。

在眾多的網路協議中,使用最廣泛的應該就是tcp協議(傳輸控制協議)了,它是一種面向連線,可靠的,基於位元組流的傳輸層協議。其執行過程分為三個階段:建立連線、交換資料、斷開連線。

在使用tcp協議交換資料前,需先建立一條連線,在不需要傳送資料的時候,需要斷開連線,以釋放資源。

建立連線

tcp協議建立連線時需要三次握手,其過程可使用以下場景來描述:

面試官:說一下tcp建立連線時三次握手的過程。

小明: 三次握手?

面試官: 嗯。

小明:握手完成了。

面試官:what?

複製**

沒錯,從小明開始問三次握手到說握手完成就是三次握手的過程,具體的過程如下:

客戶端發向服務端傳送乙個syn段,以告知客戶端要連線服務端的指定埠;

服務端收到客戶端的報文後,返回乙個對客戶端報文進行確認的ack段(syn+1)和乙個表示服務端報文的syn段;

客戶端收到服務端傳送的報文後,對服務端傳送乙個ack(服務端的syn+1),至此,客戶端和服務端就建立了一條連線。

為什麼需要3次握手而不是2次呢?

因為客戶端收到服務端的應答後,知道連線已建立成功,但是服務端並不知道自己傳送的確認報文客戶端是否收到,

所以需要客戶端對服務端的報文進行確認。

複製**

服務端一定能收到客戶端傳送的確認報文麼?

不一定,如果收不到,那麼連線就不會建立,所以,3次握手只是理論上確保建立連線的次數。那能否通過4次握手呢?

不行,再握下去就是雞生蛋,蛋生雞的問題了。

複製**

斷開連線

tcp斷開連線時需要四次握手,為什麼需要4次呢?這是由於tcp半關閉的性質造成的。所謂半關閉,就是可以傳送資料,卻不能接收資料或只能接收資料,不能傳送資料。

四次握手的過程:(由於主動斷開連線可傳送在客戶端,也可傳送在服務端,所以下面以a,b來區分兩端)

a端向b端傳送乙個fin, 告知a端即將斷開連線;

b端收到a端傳送的fin後傳送乙個ack對其進行確認;

隨後b端向再a端傳送乙個fin,以告知b端也即將斷開連線;

a端時候到b端的fin報文後,對其傳送乙個ack以示確認。

b端在對a端進行確認的時候為什麼不同時發乙個fin呢? 可以同時發。分開發是為了考慮b端在對a端確認後,可能還會給a繼續傳送資料的情況。

listen: 服務端狀態,表示服務端正在等待客戶端的連線請求,處於監聽狀態;

syn收到:服務端狀態,服務端已收到客戶端的連線請求,並對客戶端的請求傳送了ack確認(第二次握手完成);

syn_sent: 客戶端狀態,客戶端傳送syn或資料後的狀態(第一次握手完成);

established: 客戶端對服務端的syn進行確認後處於established,服務端收到客戶端傳送的ack後也會處於

established狀態(三次握手完成後的狀態);

fin_wait_1: 主動關閉的一端的狀態,傳送fin後的狀態(斷開連線時的第一次握手完成);

fin_wait_2: 主動關閉的一端的狀態,收到另一端的ack確認後的狀態(斷開連線時的第二次握手完成);

closing:主動關閉的一端的狀態,收到另一端的fin,並對其進行確認後的狀態(客戶端和服務端同時關閉的情況);

time_wait: 主動關閉的一端的狀態,,收到另一端的fin或(fin和ack)後,對其進行確認後的狀態

(斷開連線時最後一次握手完成);

close_wait: 被動關閉的一端的狀態,收到另一端傳送的fin並對其進行確認後的狀態(斷開連線時第二次握手完成);

last_ack: 被動關閉的一端的狀態,傳送fin後的狀態(斷開連線時第三次握手完成);

closed:連線徹底斷開;

複製**

tcp/ip協議族誕生之後,各個平台(window, unix)就按照此協議規範在系統層面為開發網路程式提供了統一的介面——socket。通過這個面向傳輸層協議的系統介面,我們可通過tcp/udp協議快速實現網路資料的交換,同時也可用來實現應用層協議,如http, ssl等。

socket是作業系統為上層應用實現網路資料交換提供的介面,我們可通過以下場景來理解:

當你給別人打**的時候首先要確認打給誰,其次確認打哪個號碼,通過這兩個條件就可準確的聯絡到對方。那麼在網路中傳輸資料也是同樣的道理,在網路中定位主機是通過ip來實現的,乙個ip代表了一台主機,但是每台主機有很多個埠號,所以要準確地與某個應用進行資料交換,除了ip位址外,還需要乙個埠號。有了這兩個條件,就可通過socket實現資料交換。由此可見,socket其實就相當於一部手機,兩部手機之間建立一條通路即可實現通話。

客戶端

建立scoket;

連線伺服器;

傳送、接收資料;

關閉socket連線

**實現(linux c程式設計):

#include #include #include #include #include #include #include #include #include #include int main(int argc, char *ar**)

memset(recvbuff, '0',sizeof(recvbuff));

// 建立socket

if((sockfd = socket(af_inet, sock_stream, 0)) < 0)

// 設定ip和埠

memset(&serv_addr, '0', sizeof(serv_addr));

serv_addr.sin_family = af_inet;

serv_addr.sin_port = htons(5000);

if(inet_pton(af_inet, ar**[1], &serv_addr.sin_addr)<=0)

// 連線到指定的ip和埠 -> 連線成功後即三次握手完成

if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)

// 讀資料

while ( (n = read(sockfd, recvbuff, sizeof(recvbuff)-1)) > 0)

} if(n < 0)

close(scokfd);

return 0;

}複製**

服務端

建立socket;

繫結ip和埠;

監聽客戶端的連線;

接收客戶端的連線;

傳送、接收資料

關閉socket連線;

**實現:(linux c程式設計)

#include #include #include #include #include #include #include #include #include #include int main(int argc, char *ar**)

}複製**

**出處

通過以上**,我們對socket有了乙個簡單的認識,同時也了解了資料交換的基本流程。後面會對基於tcp協議的http協議進行乙個詳細的介紹。

tcp/ip協議族

傳輸控制協議

《tcp/ip詳解 卷一》

網路程式設計之理論篇

網路通訊作為網際網路的技術支援,已被廣泛應用在軟體開發中,無論是web,服務端,客戶端還是桌面應用,都是必須掌握的一門技術。在軟體開發層面實現遠端資料交換的程式設計技術。要熟悉網路程式設計,首先需要學習網路協議的相關知識。什麼網路協議呢?網路協議是為網路中進行資料交換定義的規則,以實現按此規範進行傳...

網路程式設計之理論篇

網路通訊作為網際網路的技術支援,已被廣泛應用在軟體開發中,無論是web,服務端,客戶端還是桌面應用,都是必須掌握的一門技術。在軟體開發層面實現遠端資料交換的程式設計技術。要熟悉網路程式設計,首先需要學習網路協議的相關知識。什麼網路協議呢?網路協議是為網路中進行資料交換定義的規則,以實現按此規範進行傳...

WorkFlow之理論篇

對於工作流我也多次接觸到,雖然不是主要負責工作流,自己也私下略知一二,下面對我這階段對工作流的學習做個總結 工作流尚沒有乙個統一的 明確的定義,不同的組織和研究人員對工作流給出了各自的定義 定義1 工作流是一類能夠完全或者部分自動執行的經營過程,它根據一系列過程規則,文件 資訊或任務能夠在不同的執行...