linux網路程式設計之Socket

2021-06-22 13:46:55 字數 2321 閱讀 3366

一.socket

socket可看作是使用者程序與核心網路協議的程式設計介面.

socket可用於本機程序間的通訊,也可用於網路上不同主機間的程序通訊.

下圖顯示的是各種網路協議的位址格式:

1.struct socketaddr(通用位址結構)

通過獲取某種socketaddr結構體的首位址,不需要知道具體是哪種型別的socketaddr結構體,就可以根據位址型別字段確定結構體的內容.

因此,socket api可以接受各種型別的sockaddr結構體指標做引數,例如bind、accept、connect等函式,這些函式的引數應該設計成void *型別以便接受各種型別的指標,但是sock api的實現早於ansi c標準化,那時還沒有void *型別,因此這些函式的引數都用struct sockaddr *型別表示,即通用位址結構:

struct sockaddr ; 

2.struct socketaddr_in(ipv4位址),

struct sockaddr_in ;

struct in_addr ;

3.struct sockaddr_in6(ipv6位址),包括16位埠號、128位ip位址和一些控制欄位.

在傳遞引數之前要強制型別轉換一下,例如:

struct sockaddr_in servaddr;

bind(listen_fd, (struct sockaddr *)&servaddr, sizeof(servaddr));

二.網路位元組序

位元組序大端位元組序(big endian)

最高有效位(msb:most significant bit)儲存於最低記憶體位址處,最低有效位(lsb:lowest significant bit)儲存於最高記憶體位址處。

小端位元組序(little endian)

最高有效位(msb:most significant bit)儲存於最高記憶體位址處,最低有效位(lsb:lowest significant bit)儲存於最低記憶體位址處。

主機位元組序

不同的主機有不同的位元組序,如x86為小端位元組序,motorola 6800為大端位元組序,arm位元組序是可配置的。

網路位元組序

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

為使網路程式具有可移植性,使同樣的c**在大端和小端計算機上編譯後都能正常執行,可以呼叫以下庫函式做網路位元組序和主機位元組序的轉換。

#include

uint32_t htonl(uint32_t hostlong);

uint16_t htons(uint16_t hostshort);

uint32_t ntohl(uint32_t netlong);

uint16_t ntohs(uint16_t netshort);

h表示host,n表示network,l表示32位長整數,s表示16位短整數。例如htonl表示將32位的長整數從主機位元組序轉換為網路位元組序,例如將ip位址轉換後準備傳送。如果主機是小端位元組序,這些函式將引數做相應的大小端轉換然後返回,如果主機是大端位元組序,這些函式不做轉換,將引數原封不動地返回。

下面程式測試本機是大端機or小端機:

本機輸出的是小端位元組序,經過htonl轉換為網路位元組序(大端).

三.位址轉換

socketaddr_in的成員struct in_addr sin_addr表示32位的ip位址.

字串轉in_addr的函式:

#include

int inet_aton(const char *strptr, struct in_addr *addrptr);

in_addr_t inet_addr(const char *strptr);

int inet_pton(int family, const char *strptr, void *addrptr);

注意,轉換而成的32位數是網路位元組序的。

in_addr轉字串的函式:

char *inet_ntoa(struct in_addr inaddr);

const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);

注意,傳入的32位數也是網路位元組序的。

下面程式演示這兩種函式的用法:

四.socket型別

流式套接字(sock_stream)

提供面向連線的、可靠的資料傳輸服務,資料無差錯,無重複的傳送,且按傳送順序接收。

資料報式套接字(sock_dgram)

提供無連線服務。不提供無錯保證,資料可能丟失或重複,並且接收順序混亂。

原始套接字(sock_raw)

原文請參考: 

Linux網路程式設計之廣播

1.概念 前面介紹的tcp,udp都是單播方式,即一對一.而廣播是一台主機向區域網內的所有主機傳送資料。這時,同一網段的所有主機都能接收到資料。傳送廣播包的步驟大致如下 1 確定乙個傳送廣播的介面,如eth0 2 確定廣播的位址,通過ioctl函式,請求碼設定為siocgifbrdaddr得到廣播的...

Linux網路程式設計之廣播

1.概念 前面介紹的tcp,udp都是單播方式,即一對一.而廣播是一台主機向區域網內的所有主機傳送資料。這時,同一網段的所有主機都能接收到資料。傳送廣播包的步驟大致如下 1 確定乙個傳送廣播的介面,如eth0 2 確定廣播的位址,通過ioctl函式,請求碼設定為siocgifbrdaddr得到廣播的...

Linux 網路程式設計之UDP

1.介紹 udp協議是無連線的,不可靠傳輸的協議.伺服器與客戶端的互動不需要建立連線,沒有流量控制的功能。與tcp一樣,它也是傳輸層協議,通訊過程中需要ip位址與埠號。使用udp進行程式設計包括伺服器與客戶端,下面介紹一下伺服器與客戶端的通訊流程 伺服器流程 1 建立伺服器套接字描socket 2 ...