Linux网络编程小知识(字节序、IP格式、函数、子网掩码、DNS域名解析代码实现)
參考:網絡編程前的一些小知識–Linux筆記
作者:一只青木呀
發布時間: 2021-04-12 23:19:10
網址:https://blog.csdn.net/weixin_45309916/article/details/115560197
參考:DNS域名解析
作者:一只青木呀
發布時間: 2021-04-18 12:48:39
網址:https://blog.csdn.net/weixin_45309916/article/details/115825036
目錄
- 大端與小端
- 本地字節序(小端)
- 網絡字節序(大端)
- IP格式
- 點分十進制轉換成『二進制』
- 網絡字節序的二進制轉『點分十進制』
- 點分十進制轉網絡字節序的『二進制』
- 常用的比較好的函數
- 子網掩碼
- 子網掩碼的組成
- 子網掩碼的表示方式
- 子網掩碼的運算
- DNS域名解析
- 原理
- 代碼實現
- 測試
大端與小端
對一個多字節的數字來說在內存中的存儲是有順序的,一般分為大端與小端:
例如:0x12345678
靠近0x的為大端,尾巴為小端。
本地字節序(小端)
在我們的內存中一般都是采用小端的方式存取,也就是小端在前大端在后:
0x78 0x56 0x34 0x12
網絡字節序(大端)
但是在我們的網絡傳輸中一般都是采用大端的方式傳輸,也就是大端在前小端在后的順序:
0x12 0x34 0x56 0x78
IP格式
一般的IP格式分為點分十進制(字符串形式) 與二進制的格式(int類型)。
點分十進制轉換成『二進制』
in_addr_t inet_addr(const char *cp) //轉換網絡主機地址(點分十進制)為網絡字節序二進制值一般在TCP的綁定中,sockaddr_in這個結構體的填充時會使用到
在處理地址為255.255.255.255時也返回-1,雖然它是一個有效地址,但inet_addr()無法處理這個地址
點分十進制(Dotted Decimal Notation)全稱為點分(點式)十進制表示法,是IPv4的IP地址標識方法。IPv4中用四個字節表示一個IP地址,每個字節按照十進制表示為0 ~ 255。點分十進制就是用4個從0~255的數字,來表示一個IP地址。如192.168.1.1。
網絡字節序的二進制轉『點分十進制』
char *inet_ntoa(struct in_addr in)功能是將網絡地址轉換成“.”點隔的 字符串格式,方便我們在網絡編程的時候打印查看IP地址。
點分十進制轉網絡字節序的『二進制』
int inet_aton(const char *cp, struct in_addr *inp)功能是將一個字符串IP地址轉換為一個32位的網絡序列IP地址。如果這個函數成功,函數的返回值非零,如果輸入地址不正確則會返回零
該函數返回值指向保存點分十進制的字符串地址的指針,該字符串的空間為靜態分配 的,所以在第二次調用這個函數時,意味著上一次調用并保存的結果將會被覆蓋(重寫)。
常用的比較好的函數
int inet_pton(int family, const char *strptr, void *addrptr)const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len)現在一般都是采用inet_pton代替inet_addr
inet_ntop代替inet_ntoa
inet_pton源碼:
int inet_pton(int family, const char *strptr, void *addrptr) {if (family == AF_INET) {struct in_addr in_val;if (inet_aton(strptr, &in_val)) {memcpy(addrptr, &in_val, sizeof(in_val));return (1);}}errno = EAFNOSUPPOPT;return (-1); }inet_ntop源碼:
const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len) {const u_char *p = (const u_char*)addrptr;if (family == AF_INET) {char temp[INET_ADDRSTRLEN];snprintf(temp, sizeof(temp), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);if (strlen(temp) >= len) {errno = ENOSPC;rturn (NULL);}strcpy(strptr, temp);return (strptr);}errno = EAFNOSUPPOPT;return (NULL); }子網掩碼
當前使用的IP地址有4個字節(32)組成,即IPV4編碼方式。每個IP地址包換兩部分:網絡號和主機號。
IP地址是以網絡號和主機號來標示網絡上的主機的,我們把網絡號相同的主機稱之為本地網絡,網絡號不相同的主機稱之為遠程網絡主機,本地網絡中的主機可以直接相互通信;遠程網絡中的主機要相互通信必須通過本地網關(Gateway)來傳遞轉發數據。
子網掩碼的組成
子網掩碼是由長度為32位二進制數組成的一個地址,子網掩碼32位與IP地址32位相對應,IP地址如果某位是網絡地址,則子網掩碼為1,否則為0,例如:11111111.11111111.11111111.00000000(255.255.255.0)
子網掩碼的表示方式
-
①、11111111.11111111.11111111.00000000表示255.255.255.0
-
②、IP/24 同樣表示 11111111.11111111.11111111.00000000(斜杠后面的數字代表著1的個數)
子網掩碼的運算
子網掩碼與IP之間的運算采用“按位與”的方式計算
例如:網上找個例子
按位與,采用有0則0的原則計算,得到192.168.10.0
網絡地址計算小技巧:IP地址和子網掩碼做與運算,把IP地址的主機位直接歸0,就快速得到網絡地址。所以只要一看到IP地址和子網掩碼,就能馬上確認網絡地址。
DNS域名解析
原理
我在在通過域名解析獲取IP的過程中一般使用的是DNS域名解析。
DNS協議是一種應用層協議,他是基于UDP來實現的。
代碼實現
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h>extern int h_errno;int main(int argc, char **argv) {char *ptr, **pptr;char str[INET_ADDRSTRLEN];struct hostent *hptr; //while (--argc> 0) {ptr = *++argv; //傳入的域名if ( (hptr = gethostbyname (ptr) ) == NULL) //完成域名解析{printf("gethostbyname error for host: %s: %s",ptr, hstrerror (h_errno) );continue;}printf ("official hostname: %s\n", hptr->h_name);for (pptr=hptr->h_aliases; *pptr!= NULL; pptr++)printf ("\talias: %s\n", *pptr);switch (hptr->h_addrtype) {case AF_INET:pptr = hptr->h_addr_list;for ( ; *pptr != NULL; pptr++)printf ("\taddress: %s\n",inet_ntop (hptr->h_addrtype, *pptr, str, sizeof (str))); //hptr->h_addrtype我們獲取的IP地址break;default:printf("unknown address type");break;}}exit(0); }測試
詳細的DNS知識可繼續參照這篇博文:DNS服務(域名系統、過程、bind、配置文件、查看本設備dns)
總結
以上是生活随笔為你收集整理的Linux网络编程小知识(字节序、IP格式、函数、子网掩码、DNS域名解析代码实现)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 线性代数应该这样学
- 下一篇: linux做一个客户端与WemosD1作