計算機網路——網路程式設計套接字
IP協議有兩個版本,IPV4 和IPV6,但若每有特殊說明,預設都是指IPV4.
IP地址是在IP協議中,用來標識網路中不同主機的地址。
我們光有IP地址就可以完成通訊了嘛?有了IP地址能夠把訊息傳送到對方的機器上,但還是需要有一個其他的標識來區分出,這個程式要給哪個程式進行解析。
認識埠號:
埠號是傳輸層協議的內容:
埠號是一個2位元組16位的整數;
埠號用來標識一個程序,告訴作業系統,當前的這個資料要交給哪一個程序來處理;
IP地址+埠號能夠標識網路上的某一臺主機的某一個程序。
一個埠號只能被一個程序佔用。
網路位元組序:記憶體中的多位元組資料相對於記憶體地址有大端和小端之分,磁碟檔案中的多位元組資料相對於檔案中的偏移地址也有大端小端之分,網路資料流同樣有大端小端之分。那麼如何定義網路資料流的地址呢?
傳送主機通常將傳送緩衝區中的資料按記憶體地址從低到高的順序發出。
接收主機把從網路上接到的位元組依次儲存在接收緩衝區中,也是按記憶體地址從低到高的順序儲存。因此,網路資料流的地址應這樣規定:先發出的資料是低地址,後發出的資料是高地址。
Tcp/IP協議規定,網路資料流應採用大端位元組序,即低地址高位元組。
不管這臺主機是大端機還是小端機,都會按照這個TCP/IP規定的網路位元組序來發送/接收資料。
如果當前傳送主機是小端,就需要先將資料轉成大端;否則就忽略,直接傳送即可。
為使網路具有可移植性,使同樣的C程式碼在大端和小端計算機上編譯後都能正常執行,可以使用一下函式做網路位元組序和主機位元組序的轉換。
如果主機是小端位元組序,這些函式將引數做相應的大小端轉換然後返回。
如果主機是大端位元組序,這些函式不做轉換,將引數原封不動地返回。
socket常見API
//建立socket檔案描述符(TCP/UDP,客戶端+伺服器)
int socket(int domain,int type,int protocol);
//繫結埠號
int bind(int socket,const struct sockaddr* address, socklen_t address_len);
//接收請求(TCP,伺服器)
int accept(int socket,struct sockaddr* address,socklen_t* address_len);
//建立連線(TCP,客戶端)
int connect(int sockfd,const struct ockaddr* addr,socklen_t addrlen);
sockaddr結構
socket API是一層抽象的網路程式設計介面,適用於各種底層網路協議,如IPV4,IPV6,以及後面要將的UNIXDomain Socket,然而,各種網路協議的地址格式並不相同。
struct sockaddr:16位地址型別,14位元組資料。
struct sockaddr_in :16位地址型別:AF_INET,16位埠號,32位IP地址,8位元組填充。
struct sockaddr_un: 16位地址型別:AF_UNIX,108位元組路徑名。
IPV4和IPV6的地址格式定義在netinet/in.h中,IPV4地址用sockaddr_in結構體表示,包括16位地址型別,16位埠號和32位IP地址。
IPv4.IPV6地址型別分別定義為常數AF_INET,AF_INET6.這樣,只要取得某種sockaddr結構體的首地址,不需要知道具體是哪種型別的sockaddr結構體,就可以根據地址型別欄位確定結構體的內容。
socket API可以都用struct sockaddr*型別表示,在使用的時候需要強制轉化成sockaddr_in,這樣的好處是通用性,可以接收IPv4,IPv6,以及UNIX Domain Socket各種型別的sockaddr結構體指標做為引數。
地址轉換函式