網路程式設計學習一:IP地址轉換函式
阿新 • • 發佈:2021-11-01
IP地址轉換函式:inet_aton, inet_nota, inet_addr和inet_pton, inet_ntop
C中提供的點分十進位制IP字串與整數(二進位制)表示的轉化可以根據是否支援IPV6分為兩類,第一類是僅支援IPV4的,包括,inet_aton,inet_nota,inet_addr。它們的宣告及用法如下:
#include <arpa/inet.h> in_addr_t inet_addr(const char* strptr); int inet_aton(const char*cp, struct in_addr* inp); char* inet_ntoa( struct in_addr in); 其中in_addr為表示IPv4地址的結構體: struct in_addr { u_int32_t s_addr; }; 來自表示IPv4的socket: struct sockaddr_in { sa_family_t sin_family; //地址族 u_int16_t sin_port; //埠號 struct in_addr sin_addr; //IPv4地址結構體 }
具體用法:
#include <stdio.h> #include <arpa/inet.h> int main(){ char* ip = "127.0.0.1"; struct in_addr addr; //ip字串轉換為整數IP地址的兩種方法 addr.s_addr = inet_addr(ip); inet_aton(ip, &addr); printf("%d\n",addr.s_addr); //整數ip轉換為ip字串 char* sz1 = inet_ntoa(addr); printf("%s\n", sz1); return 0; }
注意事項,inet_nota函式內部使用了一個靜態變數儲存轉化結果,函式的返回值指向該靜態記憶體,所以inet_nota是不可重入的。舉例如下:
#include <arpa/inet.h> #include <stdio.h> int main(){ char* ip = "127.0.0.1"; char* ip2 = "172.22.1.2"; struct in_addr addr; struct in_addr addr2; inet_aton(ip, &addr); inet_aton(ip2, &addr2); char* sz1 = inet_ntoa(addr); char* sz2 = inet_ntoa(addr2); printf("%s\n", sz1); printf("%s\n", sz2); return 0; } /*輸出結果 172.22.1.2 172.22.1.2 */
第二類為同時支援IPv4和IPv6。包括,inet_pton和inet_ntop。其定義如下:
#include <netinet/in.h>
int inet_pton(int af, const char* src, void* dst);
//返回:成功返回1;輸入格式無效返回0;出錯返回-1。
const char* inet_ntop(int af, const void* src, char* dst, socklen_t cnt);
//返回:成功返回指向結果的指標;出錯返NULL。
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46
其中各引數的含義如下:
-
af引數指定地址族。可選為:AF_INET和AF_INET6;
-
src為轉換源,dst為轉換目標。這裡要注意的是,不能傳給inet_ntop一個空指標,必須是一個已分配目標大小記憶體的指標。
-
cnt引數指定目標儲存單位的大小。上面定義的兩個巨集可以幫助指定IPv4和IPv6的特定大小。
用法如下:
#include <arpa/inet.h>
#include <stdio.h>
int main(){
char* ip = "1.2.3.4";
struct in_addr addr;
int i = 0;
int *ad = &i;
inet_pton(AF_INET, ip, ad);
printf("%d\n", *ad);
char ip2[INET_ADDRSTRLEN];
char* ip3 = inet_ntop(AF_INET, ad, ip2, INET_ADDRSTRLEN);
printf("%s\n", ip2);
printf("%s\n", ip3);
return 0;
}