基本 TCP 套接字程式設計講解

2021-08-15 01:10:38 字數 4009 閱讀 5927

填寫摘要(選填)

基於 tcp 的套接字程式設計的所有客戶端和伺服器端都是從呼叫socket開始,它返回乙個套接字描述符。客戶端隨後呼叫connect 函式,伺服器端則呼叫 bind、listen 和accept函式。套接字通常使用標準的close 函式關閉,但是也可以使用 shutdown函式關閉套接字。下面針對套接字程式設計實現過程中所呼叫的函式程序分析。以下是基於 tcp 套接字程式設計的流程圖:

填寫摘要(選填)

socket 函式

套接字是通訊端點的抽象,實現端對端之間的通訊。與應用程式要使用檔案描述符訪問檔案一樣,訪問套接字需要套接字描述符。任何套接字程式設計都必須呼叫socket函式獲得套接字描述符,這樣才能對套接字進行操作。以下是該函式的描述:

填寫摘要(選填)

connect 函式

在處理面向連線的網路服務時,例如 tcp ,交換資料之前必須在請求的程序套接字和提供服務的程序套接字之間建立連線。tcp客戶端可以呼叫函式connect 來建立與 tcp 伺服器端的乙個連線。該函式的描述如下:

填寫摘要(選填)

tcp 客戶端在呼叫函式 connect 前不必非得呼叫 bind 函式,因為核心會確定源 ip位址,並選擇乙個臨時埠作為源埠號。若 tcp 套接字呼叫connect 函式將建立 tcp連線(執行三次握手),而且僅在連線建立成功或出錯時才返回,其中出錯返回可能有以下幾種情況:

若 tcp 客戶端沒有收到 syn 報文段的響應,則返回 etimeout 錯誤;

若客戶端的 syn 報文段的響應是 rst(表示復位),則表明該伺服器主機在我們指定的埠上沒有程序在等待與之連線。只是一種硬錯誤,客戶端一接收到 rst就立即返回econnerfused 錯誤;

rst 是 tcp 在發生錯誤時傳送的一種 tcp 報文段。產生 rst 的三個條件時:

目的地為某埠的 syn 到達,然而該埠上沒有正在監聽的伺服器;

tcp 想取消乙個已有連線;

tcp 接收到乙個不存在的連線上的報文段;

若客戶端發出的 syn 在中某個路由器上引發乙個目的地不可達的 icmp錯誤,這是乙個軟錯誤。客戶端主機核心儲存該訊息,並在一定的時間間隔繼續傳送 syn(即重發)。在某規定的時間後仍未收到響應,則把儲存的訊息(即 icmp 錯誤)作為ehostunreach 或enetunreach錯誤返回給進行。

bind 函式

呼叫函式 socket建立套接字描述符時,該套接字描述符是儲存在它的協議族空間中,沒有具體的位址,要使它與乙個位址相關聯,可以呼叫函式bind使其與位址繫結。客戶端的套接字關聯的位址一般可由系統預設分配,因此不需要指定具體的位址。若要為伺服器端套接字繫結位址,可以通過呼叫函式bind 將套接字繫結到乙個位址。下面是該函式的描述:

填寫摘要(選填)

對於 tcp 協議,呼叫 bind 函式可以指定乙個埠號,或指定乙個 ip 位址,也可以兩者都指定,還可以都不指定。若 tcp客戶端或伺服器端不呼叫bind 函式繫結乙個埠號,當呼叫connect 或 listen函式時,核心會為相應的套接字選擇乙個臨時埠號。一般 tcp 客戶端使用核心為其選擇乙個臨時的埠號,而伺服器端通過呼叫bind函式將埠號與相應的套接字繫結。程序可以把乙個特定的 ip 位址**到它的套接字上,但是這個 ip位址必須屬於其所在主機的網路介面之一。對於 tcp 客戶端,這就為在套接字上傳送的 ip 資料報指派了源 ip 位址。對於 tcp伺服器端,這就限定該套接字只接收那些目的地為這個 ip 位址的客戶端連線。tcp 客戶端一般不把 ip位址**到它的套接字上。當連線套接字時,核心將根據所用外出網路介面來選擇源 ip位址,而所用外出介面則取決於到達伺服器端所需的路徑。若 tcp 伺服器端沒有把 ip 位址**到它的套接字上,核心就把客戶端傳送的syn 的目的 ip 位址作為伺服器端的源 ip 位址。

在程序所執行的機器上,指定的位址必須有效,不能指定其他機器的位址;

位址必須和建立套接字時的位址族所支援的格式相匹配;

埠號必須不小於1024,除非該程序具有相應的特權(超級使用者);

一般只有套接字端點能夠與位址繫結,儘管有些協議允許多重繫結;

listen 函式

在編寫伺服器程式時需要使用監聽函式 listen。伺服器程序不知道要與誰連線,因此,它不會主動地要求與某個程序連線,只是一直監聽是否有其他客戶程序與之連線,然後響應該連線請求,並對它做出處理,乙個服務程序可以同時處理多個客戶程序的連線。listen函式描述如下:

填寫摘要(選填)

listen 函式僅由 tcp 伺服器呼叫,它有以下兩種作用:

當 socket 函式建立乙個套接字時,若它被假設為乙個主動套接字,即它是乙個將呼叫connect發起連線的客戶端套接字。listen 函式把乙個未連線的套接字轉換成乙個被動套接字,指示核心應該接受指向該套接字的連線請求;

listen 函式的第二個引數規定核心應該為相應套接字排隊的最大連線個數;

listen 函式一般應該在呼叫socket 和bind 這兩個函式之後,並在呼叫 accept 函式之前呼叫。核心為任何乙個給定監聽套接字維護兩個佇列:

未完成連線佇列,每個這樣的 syn 報文段對應其中一項:已由某個客戶端發出並到達伺服器,而伺服器正在等待完成相應的 tcp三次握手過程。這些套接字處於 syn_revd 狀態;

已完成連線佇列,每個已完成 tcp 三次握手過程的客戶端對應其中一項。這些套接字處於 established 狀態;

accept 函式

accept 函式由 tcp伺服器呼叫,用於從已完成連線佇列隊頭返回下乙個已完成連線。如果已完成連線隊列為空,那麼程序被投入睡眠。該函式的返回值是乙個新的套接字描述符,返回值是表示已連線的套接字描述符,而第乙個引數是伺服器監聽套接字描述符。乙個伺服器通常僅僅建立乙個監聽套接字,它在該伺服器的生命週期內一直存在。核心為每個由伺服器程序接受的客戶連線建立乙個已連線套接字(表示tcp 三次握手已完成),當伺服器完成對某個給定客戶的服務時,相應的已連線套接字就會被關閉。該函式描述如下:

填寫摘要(選填)

fork 和 exec 函式

填寫摘要(選填)

exec6個函式在函式名和使用語法的規則上都有細微的區別,下面就從可執行檔案查詢方式、引數傳遞方式及環境變數這幾個方面進行比較。

查詢方式:前4個函式的查詢方式都是完整的檔案目錄路徑 pathname,而最後兩個函式(也就是以p結尾的兩個函式)可以只給出檔名 filename,系統就會自動按照環境變數 「$path」所指定的路徑進行查詢。

引數傳遞方式:exec序列函式的引數傳遞有兩種方式:一種是逐個列舉的方式,而另一種則是將所有引數整體構造指標陣列傳遞。在這裡是以函式名的第5位字母來區分的,字母為「l」(list)的表示逐個列舉引數的方式,其語法為 const char *arg;字母為「v」(vertor)的表示將所有引數整體構造指標陣列傳遞,其語法為 char *const argv。讀者可以觀察execl()、execle()、execlp() 的語法與 execv()、execve()、execvp()的區別。這裡的引數實際上就是使用者在使用這個可執行檔案時所需的全部命令選項字串(包括該可執行程式命令本身)。要注意的是,這些引數必須以null結束。

環境變數:exec 序列函式可以預設系統的環境變數,也可以傳入指定的環境變數。這裡以「e」(environment)結尾的兩個函式 execle() 和 execve() 就可以在 envp中指定當前程序所使用的環境變數。

填寫摘要(選填)

併發伺服器

當要求乙個伺服器同時為多個客戶服務時,需要併發伺服器。tcp 併發伺服器,它們為每個待處理的客戶端連線呼叫 fork函式派生乙個子程序。當乙個連線建立時,accept 返回,伺服器接著呼叫 fork函式,然後由子程序服務客戶端,父程序則等待另乙個連線,此時,父程序必須關閉已連線套接字。

close 和 shutdown 函式

當要關閉套接字時,可使用 close 和 shutdown 函式,其描述如下:

填寫摘要(選填)

getsockname 和 getpeername 函式

填寫摘要(選填

基本TCP套接字程式設計

基本tcp客戶 伺服器程式的套接字函式 返回 若成功則為非負描述符,若則為 1 其中family引數指明協議族,為某個常值。該引數也往往稱為協議域。family 說明af inet ipv4協議 af inet6 ipv6協議 af local unix域協議 af route 路由套接字 af k...

基本TCP套接字程式設計

經過最近一段時間的系統學習,對於傳輸協議中tcp協議的套接字程式設計以及11中狀態轉化有了一定的認識,現在做出 以下總結 上圖是幾乎所有教科書上關於tcp客戶端 伺服器通訊過程中api函式的彙總。首先看伺服器端 1 服務端以被動連線的方式參與通訊,因此首先呼叫socket int family,in...

基本TCP套接字程式設計

tcp客戶與伺服器程序之間典型事件時間表 socket函式 includeint socket int family,int type,int protocol family引數執行協議族,該引數也往往被稱為協議域。是以下某個常值 type引數指明套接字型別,是以下某個常值 protocol引數應設...