Linux 網路程式設計 基本函式

2021-07-10 07:48:18 字數 2870 閱讀 1653

我們現在所使用的網路tcp/ip 其實就是大牛們幾十年前發明的東西,經過幾十年的發展,雖然出現了很多的其它協議,但是底層的東西卻基本穩定。現在的b/s ,c/s 等的網路體系都是執行在這樣乙個網路體系之上的。

#include

#include

int  socket(int domin ,int type, int protocol);

這是執行網路io 的第一步,指定期望的通訊型別。

@domin   協議型別

@type      套接字型別

@protocol  協議型別常值

這裡有乙個tcp/ip 伺服器的基本流程。

這個函式成功後返回乙個小的非負整數值,我們稱之為套接字描述符,簡稱sockfd,這裡sockfd 僅僅指定了協議族和套接字模型,並沒有指定本地協議或遠端協議位址。

#include

#include

int  connect (int sockfd, const struct sockaddr * addr,socklen_t addrlen);

@sockfd   套接字描述符

@sockaddr   套接字結構體指標

@addrlen     該結構體大小

客戶在呼叫這個函式之前不必非呼叫bind 需要的話,核心會提供給它乙個確定的ip位址,並且選擇乙個臨時的埠。

如果是tcp 連線,傳說中的三路握手就再這個函式上,它返回有以下的幾種情況:

1.若tcp客戶沒有收到syn分節的響應返回etimedout 錯誤,比如說bsd 呼叫這個函式後傳送乙個syn 若無響應則等待6s後再次傳送,下一次等24s在總共75秒的等待後,仍然無響應返回本錯誤,但是有些使用的則是超時機制。

2.若對使用者的syn 響應的是rst,則表示該伺服器的在我們指定的埠上沒有連線的程序,就是服務的程式。這就是個硬傷,所以一但接收到這個標記就會立刻返回econnrefused錯誤。

發生rst 的條件有以下的三種情況:

@目的地某埠的syn 到達,然而該埠上並沒有相應的服務程式。

@tcp 想取消乙個已有的鏈結。

@tcp 接收到乙個根本不存在的的鏈結上的分節。

3.若客戶發出的syn 在中間的某個路由器上引發乙個destination unreachable (目的不可達)icmp錯誤,則認為是乙個軟錯誤。客戶主機核心儲存這個訊息,然後嘗試集序傳送syn ,當然在一定的等待秒數之後,核心就會把自己儲存的錯誤資訊傳送給相應的程序。當然也可能出現以下的錯誤原因:

#按照本地路由表根本沒有到達遠端系統的路徑;

#connect 呼叫根本不等待就返回;

下面是一些問題的說法:

@當我們向根本不存在的ip傳送請求的時候,它將永遠收不到arp 響應,當超時後就會得到該錯誤了。(本地子網並不存在的ip)

@當我們嘗試鏈結乙個沒有執行的主機,直接就會得到鏈結失敗的錯誤。

@我們指定乙個網際網路不可到達的ip的時候,就會發現icmp 錯誤

connect 函式將當前套接字從closed 狀態轉移到syn_sent 狀態正常情況下在 轉移到established狀態。

#include

int bind(int socket ,const struct sockaddr *address, socklen_t address_len);

這個函式把本協議位址賦予乙個套接字,對與網際協議,協議位址是32位的ipv4位址或128位的ipv6位址與16位的tcp或udp 埠號組合。

@sockfd 套接字

@是乙個指向特定於協議的位址結構指標

@該結構位址長度

對與tcp 來說,呼叫這個函式可以指定乙個埠號,或者指定乙個ip位址,也可以全部指定或者全部都不指定。

對與客戶的來說讓核心隨意選定埠是正常的所以它可以不呼叫繫結函式,但是對與伺服器來說就是及其罕見的,因為埠是伺服器標識的一部分。

程序可以把ip和埠繫結在這個套接字上,這樣這個伺服器程序就會只接受向這個ip埠來的資訊,正好符和我們的一貫做法。但是tcp客戶一般並不需要這樣做,核心會根據所用的外出網路介面來選擇源ip位址。而外出埠再則是根據向伺服器的位址路徑來決定的。

當埠設定為0的時候,核心會在這個函式被呼叫時選擇乙個臨時埠。我們也回發現這個函式的第二個引數是const 的,也就是說如果核心自己選定了引數我們就不能直接獲取這個位址和埠號,但是我們可以使用 getsockname( ) 函式來獲取這些資訊。

#include

#include

int listen (int sockfd, int backlog);

這個函式只做兩件事情:

socket建立乙個套接字,然後假設在這個套接字是乙個主動的套接字,他是乙個將呼叫connect 發起鏈結的客戶套接字。listen 把乙個未鏈結的套接字轉換成乙個被動套接字,指示核心應該接受指向該套接字的鏈結請求。

第二個引數指定了核心規定應該為相應套接字排隊的最大鏈結數。

本函式應該在呼叫socket 和 bind 這兩個函式之後,並在呼叫accept 函式之前呼叫。

其中第二個引數是兩個佇列的長度總和,未完成鏈結佇列,已完成鏈結佇列。

每個這樣的syn對應其中一樣,正在等待完成相應的tcp三路握手過程,這些套接字處在syn_rcvd狀態。

每個已完成tcp三路握手過程的客戶對應其中的一項,這些套接字是 established狀態。

網上找來乙個圖。還是unp書上的。

#include

int accept(int sockfd ,struct sockaddr * cliaddr, socklen_t *addrlen)

這個函式成功呼叫後返回乙個由核心自動生成的乙個全新的描述符,代表與所返回客戶的tcp鏈結。本函式最多返回三個值乙個可能的新的套接字描述符,也可能是出錯的整數,客戶程序的協議位址,以及該指標的大小。如果對使用者位址不感興趣,我們就可以把引數設定為空指標。

網路程式設計 基本函式

位元組排序函式 include 返回網路位元組序的值 uint16 t htons uint16 t host16bitvalue uint32 t htonl uint32 t host32bitvalue 返回主機位元組序的值 uint16 t ntohs uint16 t net16bitva...

Linux網路程式設計常用函式

計算機資料儲存有兩種位元組優先順序 高位位元組優先和低位位元組優先。internet上資料以高位位元組優先順 序在網路上傳輸,所以對於在內部是以低位位元組優先方式儲存資料的機器,在internet上傳輸資料時就需 要進行轉換。我們要討論的第乙個結構型別是 struct sockaddr,該型別是用來...

Linux網路程式設計 poll函式

作用 監視並等待多個檔案描述符的屬性變化。函式原型 int poll struct pollfd fds,nfds t nfds,int timeout 函式引數意義 fds 指向乙個結構體陣列的第0個元素的指標,每個陣列元素都是乙個struct pollfd結構,用於指定測試某個給定的fd的條件。...