一.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 ...