嵌入式Linux網絡編程之:網絡基礎編程
10.2網絡基礎編程
10.2.1socket概述
1.socket定義
在Linux中的網絡編程是通過socket接口來進行的。人們常說的socket是一種特殊的I/O接口,它也是一種文件描述符。socket是一種常用的進程之間通信機制,通過它不僅能實現本地機器上的進程之間的通信,而且通過網絡能夠在不同機器上的進程之間進行通信。
每一個socket都用一個半相關描述{協議、本地地址、本地端口}來表示;一個完整的套接字則用一個相關描述{協議、本地地址、本地端口、遠程地址、遠程端口}來表示。socket也有一個類似于打開文件的函數調用,該函數返回一個整型的socket描述符,隨后的連接建立、數據傳輸等操作都是通過socket來實現的。
2.socket類型
常見的socket有3種類型如下。
(1)流式socket(SOCK_STREAM)。
流式套接字提供可靠的、面向連接的通信流;它使用TCP協議,從而保證了數據傳輸的正確性和順序性。
(2)數據報socket(SOCK_DGRAM)。
數據報套接字定義了一種無連接的服務,數據通過相互獨立的報文進行傳輸,是無序的,并且不保證是可靠、無差錯的。它使用數據報協議UDP。
(3)原始socket。
原始套接字允許對底層協議如IP或ICMP進行直接訪問,它功能強大但使用較為不便,主要用于一些協議的開發。
10.2.2地址及順序處理
1.地址結構相關處理
(1)數據結構介紹。
下面首先介紹兩個重要的數據類型:sockaddr和sockaddr_in,這兩個結構類型都是用來保存socket信息的,如下所示:
structsockaddr
{
unsignedshortsa_family;/*地址族*/
charsa_data[14];/*14字節的協議地址,包含該socket的IP地址和端口號。*/
};
structsockaddr_in
{
shortintsa_family;/*地址族*/
unsignedshortintsin_port;/*端口號*/
structin_addrsin_addr;/*IP地址*/
unsignedcharsin_zero[8];/*填充0以保持與structsockaddr同樣大小*/
};
這兩個數據類型是等效的,可以相互轉化,通常sockaddr_in數據類型使用更為方便。在建立socketadd或sockaddr_in后,就可以對該socket進行適當的操作了。
(2)結構字段。
表10.1列出了該結構sa_family字段可選的常見值。
表10.1
結構定義頭文件 | #includenetinet/in.h> |
sa_family | AF_INET:IPv4協議 |
AF_INET6:IPv6協議 | |
AF_LOCAL:UNIX域協議 | |
AF_LINK:鏈路地址協議 | |
AF_KEY:密鑰套接字(socket) |
sockaddr_in其他字段的含義非常清楚,具體的設置涉及其他函數,在后面會有詳細的講解。
2.數據存儲優先順序
(1)函數說明。
計算機數據存儲有兩種字節優先順序:高位字節優先(稱為大端模式)和低位字節優先(稱為小端模式,PC機通常采用小端模式)。Internet上數據以高位字節優先順序在網絡上傳輸,因此在有些情況下,需要對這兩個字節存儲優先順序進行相互轉化。這里用到了4個函數:htons()、ntohs()、htonl()和ntohl()。這4個地址分別實現網絡字節序和主機字節序的轉化,這里的h代表host,n代表network,s代表short,l代表long。通常16位的IP端口號用s代表,而IP地址用l來代表。
(2)函數格式說明。
表10.2列出了這4個函數的語法格式。
表10.2 htons等函數語法要點
所需頭文件 | #includenetinet/in.h> |
函數原型 | uint16_thtons(unit16_thost16bit) |
函數傳入值 | host16bit:主機字節序的16位數據 |
host32bit:主機字節序的32位數據 | |
net16bit:網絡字節序的16位數據 | |
net32bit:網絡字節序的32位數據 | |
函數返回值 | 成功:返回要轉換的字節序 |
出錯:-1 |
| 調用該函數只是使其得到相應的字節序,用戶不需清楚該系統的主機字節序和網絡字節序是否真正相等。如果是相同不需要轉換的話,該系統的這些函數會定義成空宏。 |
3.地址格式轉化
(1)函數說明。
通常用戶在表達地址時采用的是點分十進制表示的數值(或者是以冒號分開的十進制IPv6地址),而在通常使用的socket編程中所使用的則是二進制值,這就需要將這兩個數值進行轉換。這里在IPv4中用到的函數有inet_aton()、inet_addr()和inet_ntoa(),而IPv4和IPv6兼容的函數有inet_pton()和inet_ntop()。由于IPv6是下一代互聯網的標準協議,因此,本書講解的函數都能夠同時兼容IPv4和IPv6,但在具體舉例時仍以IPv4為例。
這里inet_pton()函數是將點分十進制地址映射為二進制地址,而inet_ntop()是將二進制地址映射為點分十進制地址。
(2)函數格式。
表10.3列出了inet_pton函數的語法要點。
表10.3 inet_pton函數語法要點
所需頭文件 | #includearpa/inet.h> | |
函數原型 | intinet_pton(intfamily,constchar*strptr,void*addrptr) | |
函數傳入值 | family | AF_INET:IPv4協議 |
AF_INET6:IPv6協議 | ||
strptr:要轉化的值 | ||
addrptr:轉化后的地址 | ||
函數返回值 | 成功:0 | |
出錯:-1 |
linux相關文章:linux教程
評論