天天看點

net_pton函數和inet_ntop函數

純粹copy,記錄一下,講的很細

  這兩個函數是随IPv6出現的新函數,對于IPv4位址和IPv6位址都适用。函數名中的p和n非别代表表達(presentation)和數值(numeric)。位址的表達格式通常是ASCII字元串,數值格式則是存放到套接字位址結構中的二進制值。函數如下:

  1. #include<arpa/inet.h>
  2. int inet_pton(int family, const char *strptr, void *addrptr);
  3. 傳回:若成功則為 ,若輸入不是有效的表達格式則為 ,若出錯則為
  4. const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);
  5. 傳回:若成功則為指向結果的指針, 若出錯則為 NULL

        這兩個函數的family參數既可以是AF_INET,也可以是AF_INET6。如果以不被支援的位址族作為family的參數,這兩個函數就都傳回一個錯誤,并将errno置為EAFNOSUPPORT。

第一個函數嘗試轉換由strptr指針所指的字元串,并通過addrptr指針存放二進制結果。若成功則傳回1,否則如果對所指定的family而言輸入的字元串不是有效的表達式,那麼值為0。

        inet_ntop進行相反的轉換,從數值格式(addrptr)轉換到表達格式(strptr)。len參數是目标存儲單元的大小,以免該函數溢出其調用者的緩沖區。為有助于指定這個大小,在<netinet/in.h>頭檔案中有如下定義:

  1. #define INET_ADDRSTRLEN 16
  2. #define INET6_ADDRSTRLEN 46

        如果len太小,不足以容納表達式結果(包括結尾的空字元),那麼傳回一個空指針,并置errno為ENOSPC。

        inet_ntop函數的strptr參數不可以是一個空指針。調用者必須為目标存儲單元配置設定記憶體并指定其大小。調用成功時,這個指針就是該函數的傳回值。

        即使系統還不支援IPv6,也可以采取下列措施開始使用這些新函數,即用代碼

  1. inet_pton(AF_INET, cp, &foo.sin_addr);
  2. 代替代碼
  3. foo.sin_addr.s_addr = inet_addr(cp);
  4. 再用代碼
  5. char str[INET_ADDRSTRLEN];
  6. ptr = inet_ntop(AF_INET, &foo.sin_addr, str, sizeof(str));
  7. 代替代碼
  8. ptr = inet_ntoa(foo.sin_addr);

下面給出隻支援IPv4的inet_pton函數的簡單定義和隻支援IPv4的inet_ntop函數的簡化版本。

  1. int inet_pton(int family, const char *strptr, void *addrptr)
  2. {
  3. if(family == AF_INET) {
  4. struct in_addr in_val;
  5. if (inet_aton(strptr, &in_val)) {
  6. memcpy(addrptr, &in_val, sizeof(struct in_addr));
  7. return ( );
  8. }
  9. }
  10. errno = EAFNOSUPPORT;
  11. return ( );
  12. }
  1. const char * inet_ntop(int family, const void *addrptr, char *strptr, size_t lne)
  2. {
  3. const u_char *p = ( const u_char *) addrptr;
  4. if(family == AF_INET) {
  5. char temp[INET_ADDRSTRLEN];
  6. snprintf(temp, sizeof(temp), "%d.%d.%d.%d", p[ ], p[ ], p[ ], p[ ]);
  7. if ( strlen(temp) >= len){
  8. errno = ENOSPC;
  9. return ( NULL);
  10. }
  11. strcpy(strptr, temp);
  12. return (strptr);
  13. }
  14. errno = EAFNOSUPPORT;
  15. return ( NULL);
  16. }