解析socket程式設計的相關函式

2021-08-26 14:42:52 字數 3733 閱讀 3524

1.什麼是套接字

乙個完整的網路通訊需要乙個五元組來標識:協議、本地位址、本地埠號、遠端位址、遠端埠號。

tcp用主機的ip位址加上主機上的埠號作為tcp連線的端點,這種端點就叫做套接字

流式套接字(sock_stream):tcp(the transmission control protocol)協議。

流式套接字用於提供面向連線、可靠的資料傳輸服務。該服務將保證資料能夠實現無差錯、無重**送,並按順序接收

資料報套接字(sock_dgram):udp(user datagram protocol)協議

資料報套接字提供了一種無連線的服務。該服務並不能保證資料傳輸的可靠性,資料有可能在傳輸過程中丟失或出現資料重複,且無法保證順序地接收到資料。進行資料的傳輸 

原始套接字(sock_raw):ip、 icmp協議

原始套接字(socket_raw)允許對較低層次的協議直接訪問,比如ip、 icmp協議,它常用於檢驗新的協議實現,或者訪問現有服務中配置的新裝置,因為raw socket可以自如地控制windows下的多種協議,能夠對網路底層的傳輸機制進行控制,所以可以應用原始套接字來操縱網路層和傳輸層應用。

比如,我們可以通過raw socket來接收發向本機的icmp、igmp協議包,或者接收tcp/ip棧不能夠處理的ip包,也可以用來傳送一些自定包頭或自定協議的ip包。網路監聽技術很大程度上依賴於socket_raw

2.什麼是大小端(主機位元組序)

乙個整型變數一般是32位的,由4個位元組組成。這些位元組的位址是有高低位址之分

傳送主機通常將傳送緩衝區中的資料按記憶體位址從低到⾼的順序發出;

接收主機把從網路上接到的位元組依次儲存在接收緩衝區中,也是按記憶體位址從低到⾼的順序儲存;

如果將低8位存放在4個位元組中的

低位址位,稱為

小端位元組序

如果將低8位存放在4個位元組的

高位址位,則為

大端位元組序

網路位元組序被規定為大端位元組序!!!

3.什麼是網路位元組序,為什麼要考慮網路位元組序

網路位元組順序是tcp/ip中規定好的一種資料表示格式,它與cpu型別、作業系統等無關,從而可以保證資料在不同主機之間傳輸時能夠被正確解釋。

因為一台主機有可能是⼤端機或者是⼩端機, 所以對資料的儲存方式是不一樣的,為了解決這一差異,tcp/ip規定的網路位元組序來傳送/接收資料;

如果當前傳送主機是⼩端, 就需要先將資料轉成⼤端; 否則就忽略, 直接傳送即可;

4.常見的socket api

// 建立 socket ⽂件描述符 (tcp/udp, 客戶端 + 伺服器)

//根據指定的位址族,資料型別和協議來分配乙個套接字的描述字及其所用的資源。

//引數:

協議族(ipv4)af_inet    型別(位元組流)sock_stream指定協議protocol當引數為0時,會自動選擇第二個引數型別對應的預設協議。

//引數:

協議族(ipv6)pf_inet    型別(資料報)sock_dgram指定協議protocol當引數為0時,會自動選擇第二個引數型別對應的預設協議。

int socket(int domain, int type, int protocol);     //

繫結端⼝號 (tcp/udp, 伺服器)     

int bind(int socket, const (struct sockaddr *)address,socklen_t address_len);        //返回的fd

addr_in結構體的強轉

len//

開始監聽socket (tcp, 伺服器)

int listen(int socket, int backlog); //

接收請求 (tcp, 伺服器)

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

//建⽴連線 (tcp, 客戶端)

int connect(int sockfd, const struct sockaddr *addr,

socklen_t addrlen);

5.如何理解accept返回值

返回的是乙個不同的sock_fd,這個socket儲存的是你客戶端的socket資訊,socket程式設計服務端客戶端都需要知道 協議、伺服器ip、伺服器端口、客戶端ip、客戶端埠這些資訊

成功返回之後,tcp伺服器與客戶端將使用這個新的sock_fd進行通訊,失敗返回乙個非法值(巨集)

6.如何理解listen的第二個引數

三次握手的 過程中會維護著兩個佇列syn_rcvd(處於三次握手中的),established(已經完成三次握手,但還沒被伺服器accept的)

1:未完成佇列:每個這樣的syn分節對應其中一項,已有某個客戶端發出並到達伺服器,而伺服器正在等待完成相應的tcp三路握手過程。這些套介面處於syn_rcvd

2:已完成佇列:每個已經完成tcp三次握手過程的客戶對應其中一項。 這些套介面處於established

第二個引數就是未完成佇列的大小

指的是在完成tcp三次握手後的佇列。即在系統accept之前的佇列。

如果系統沒有呼叫accpet把這個佇列的資料拿出來。一旦這個佇列滿了。未連線佇列的請求過不來。導致未連線佇列裡的請求會超時或者拒絕。如果系統呼叫了accpet佇列接受請求資料。那麼就會把接受到請求移除已完成佇列。 這時候已完成佇列又可以使用了。

最後 說了如果開啟了syncookies  忽略listen的第二個引數。

7.bind失敗可能的原因

試圖繫結乙個已經在使用的埠。

試圖繫結乙個正在處於time_wait狀態的埠。

繫結乙個為小於1024的埠號,因為1到1024是保留埠號

bind 最常見的用法是關聯埠號和伺服器,並使用萬用字元位址(inaddr_any),它允許任何介面為到來的連線所使用。

socket程式設計相關函式

本文旨在整理一下linux下socket程式設計時一些常用的一些理解總結,如有不足希望大家批評指點 linux version 3.10.0 862.14.4.el7.x86 64 gcc version 4.8.5 20150623 red hat 4.8.5 28 gcc tcp的伺服器端soc...

socket網路程式設計的相關函式

1.wsastartup函式 用於初始化winsock 宣告 intwsastarup word wversionrequested,lpwsadata lpwsadata 引數 wversionrequested 要求使用winsock的最低版本號 lpwsadata winsock的詳細資料 返...

socket函式解析

網路程式設計中的套接字系統呼叫socket 用來獲得檔案描述符。socket 函式的原型如下 int socket int domian,int type,int protocol 這個函式建立乙個協議族為domain 協議型別type 協議編號為protocol的套接字檔案描述符。如果函式呼叫成功...