詳解inet_pton()和inet_ntop()函數(shù)
inet_pton是一個IP地址轉(zhuǎn)換函數(shù),可以在將IP地址在“點分十進制”和“二進制整數(shù)”之間轉(zhuǎn)換,而且inet_pton和inet_ntop這2個函數(shù)能夠處理ipv4和ipv6。算是比較新的函數(shù)了。
1.把ip地址轉(zhuǎn)化為用于網(wǎng)絡(luò)傳輸?shù)亩M制數(shù)值
int inet_aton(const char *cp, struct in_addr *inp);
inet_aton() 轉(zhuǎn)換網(wǎng)絡(luò)主機地址ip(如192.168.1.10)為二進制數(shù)值,并存儲在struct in_addr結(jié)構(gòu)中,即第二個參數(shù)*inp,函數(shù)返回非0表示cp主機有地有效,返回0表示主機地址無效。(這個轉(zhuǎn)換完后不能用于網(wǎng)絡(luò)傳輸,還需要調(diào)用htons或htonl函數(shù)才能將主機字節(jié)順序轉(zhuǎn)化為網(wǎng)絡(luò)字節(jié)順序)
in_addr_t inet_addr(const char *cp);
inet_addr函數(shù)轉(zhuǎn)換網(wǎng)絡(luò)主機地址(如192.168.1.10)為網(wǎng)絡(luò)字節(jié)序二進制值,如果參數(shù)char *cp無效,函數(shù)返回-1(INADDR_NONE),這個函數(shù)在處理地址為255.255.255.255時也返回-1,255.255.255.255是一個有效的地址,不過inet_addr無法處理;
2.將網(wǎng)絡(luò)傳輸?shù)亩M制數(shù)值轉(zhuǎn)化為成點分十進制的ip地址
char *inet_ntoa(struct in_addr in);
inet_ntoa 函數(shù)轉(zhuǎn)換網(wǎng)絡(luò)字節(jié)排序的地址為標準的ASCII以點分開的地址,該函數(shù)返回指向點分開的字符串地址(如192.168.1.10)的指針,該字符串的空間為靜態(tài)分配的,這意味著在第二次調(diào)用該函數(shù)時,上一次調(diào)用將會被重寫(復(fù)蓋),所以如果需要保存該串最后復(fù)制出來自己管理!
我們?nèi)绾屋敵鲆粋€點分十進制的IP呢?我們來看看下面的程序:
#include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> int main() { struct in_addr addr1,addr2; ulong l1,l2; l1= inet_addr("192.168.0.74"); l2 = inet_addr("211.100.21.179"); memcpy(&addr1, &l1, 4); memcpy(&addr2, &l2, 4); printf("%s : %s\n", inet_ntoa(addr1), inet_ntoa(addr2)); //注意這一句的運行結(jié)果 printf("%s\n", inet_ntoa(addr1)); printf("%s\n", inet_ntoa(addr2)); return 0; }
實際運行結(jié)果如下:
192.168.0.74 : 192.168.0.74 //從這里可以看出,printf里的inet_ntoa只運行了一次。
192.168.0.74
211.100.21.179
inet_ntoa返回一個char *,而這個char *的空間是在inet_ntoa里面靜態(tài)分配的,所以inet_ntoa后面的調(diào)用會覆蓋上一次的調(diào)用。第一句printf的結(jié)果只能說明在printf里面的可變參數(shù)的求值是從右到左的,僅此而已。
3.新型網(wǎng)路地址轉(zhuǎn)化函數(shù)inet_pton和inet_ntop
這兩個函數(shù)是隨IPv6出現(xiàn)的函數(shù),對于IPv4地址和IPv6地址都適用,函數(shù)中p和n分別代表表達(presentation)和數(shù)值(numeric)。地址的表達格式通常是ASCII字符串,數(shù)值格式則是存放到套接字地址結(jié)構(gòu)的二進制值。
#include <arpe/inet.h> int inet_pton(int family, const char *strptr, void *addrptr); //將點分十進制的ip地址轉(zhuǎn)化為用于網(wǎng)絡(luò)傳輸?shù)臄?shù)值格式 返回值:若成功則為1,若輸入不是有效的表達式則為0,若出錯則為-1 const char * inet_ntop(int family, const void *addrptr, char *strptr, size_t len); //將數(shù)值格式轉(zhuǎn)化為點分十進制的ip地址格式 返回值:若成功則為指向結(jié)構(gòu)的指針,若出錯則為NULL
(1)這兩個函數(shù)的family參數(shù)既可以是AF_INET(ipv4)也可以是AF_INET6(ipv6)。如果,以不被支持的地址族作為family參數(shù),這兩個函數(shù)都返回一個錯誤,并將errno置為EAFNOSUPPORT.
(2)第一個函數(shù)嘗試轉(zhuǎn)換由strptr指針所指向的字符串,并通過addrptr指針存放二進制結(jié)果,若成功則返回值為1,否則如果所指定的family而言輸入字符串不是有效的表達式格式,那么返回值為0.
(3)inet_ntop進行相反的轉(zhuǎn)換,從數(shù)值格式(addrptr)轉(zhuǎn)換到表達式(strptr)。inet_ntop函數(shù)的strptr參數(shù)不可以是一個空指針。調(diào)用者必須為目標存儲單元分配內(nèi)存并指定其大小,調(diào)用成功時,這個指針就是該函數(shù)的返回值。len參數(shù)是目標存儲單元的大小,以免該函數(shù)溢出其調(diào)用者的緩沖區(qū)。如果len太小,不足以容納表達式結(jié)果,那么返回一個空指針,并置為errno為ENOSPC。
4.示例
inet_pton(AF_INET, ip, &foo.sin_addr); // 代替 foo.sin_addr.addr=inet_addr(ip); char str[INET_ADDRSTRLEN]; char *ptr = inet_ntop(AF_INET,&foo.sin_addr, str, sizeof(str)); // 代替 ptr = inet_ntoa(foo.sin_addr)
總結(jié)
以上所述是小編給大家介紹的inet_pton()和inet_ntop()函數(shù),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!
相關(guān)文章
人工智能開發(fā)語言排行榜: 不死Java, 不朽C/C++, 新貴Python【推薦】
這篇文章主要介紹了人工智能開發(fā)語言排行榜: 不死Java, 不朽C/C++, 新貴Python,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-08-082019最新系統(tǒng)學(xué)習(xí)路線零基礎(chǔ)如何轉(zhuǎn)行大數(shù)據(jù)
今天小編給你一個大數(shù)據(jù)工程師具體的學(xué)習(xí)路線圖。非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧2019-06-06如何配置openai的返回Stream數(shù)據(jù)并轉(zhuǎn)發(fā)到h5頁面按markdown格式流式輸出(最新推薦)
這篇文章主要介紹了如何配置openai的返回Stream數(shù)據(jù)并轉(zhuǎn)發(fā)到h5頁面按markdown格式流式輸出,本文通過示例代碼演示如何使用OpenAI?API來實現(xiàn)流式輸出并分段加載,需要的朋友可以參考下2023-05-05