Socket中常見的幾個轉換函數(htonl,htons,ntohl,ntohs,inet_addr,inet_ntoa)

Socket中常見的幾個轉換函數(htonl,htons,ntohl,ntohs,inet_addr,inet_ntoa) 
2009年12月27日 
  htonl() htons() ntohl() ntohs()及inet_ntoa() inet_addr()的用法 
  注:其中的h表示“host”,n表示“net”,l表示“long”, 
                      s表示“short”a表示“ascii”,ddr表示“in_addr結構體” 
  現在我們很幸運,因爲我們有很多的函數來方便地操作 IP 地址。沒有 必要用手工計算它們,也沒有必要用"一個sockaddr_in結構體變量ina,你有一個IP地址"132.241.5.10" 要儲存在其中,你就要用到函數inet_addr(),將IP地址從點數格式轉換成無符號長整型。使用方法如下: 
  ina.sin_addr.s_addr = inet_addr("132.241.5.10"); 
  注意,inet_addr()返回的地址已經是網絡字節格式,所以你無需再調用 函數htonl()。 
  現在你可以將IP地址轉換成長整型了。有沒有其相反的方法呢? 它可以將一個in_addr結構體輸出成點數格式?這樣的話,你就要用到函數 inet_ntoa()("ntoa"的含義是"network to ascii"),就像這樣: 
  printf("%s",inet_ntoa(ina.sin_addr)); 
  它將輸出IP地址。需要注意的是inet_ntoa()將結構體in-addr作爲一 個參數,不是長整形。同樣需要注意的是它返回的是一個指向一個字符的指針。它是一個由inet_ntoa()控制的靜態的固定的指針,所以每次調用 inet_ntoa(),它就將覆蓋上次調用時所得的IP地址。例如: 
  char *a1, *a2; 
  a1 = inet_ntoa(ina1.sin_addr); /* 這是198.92.129.1 */ 
  a2 = inet_ntoa(ina2.sin_addr); /* 這是132.241.5.10 */ 
  printf("address 1: %s ",a1); 
  printf("address 2: %s ",a2); 
  輸出如下: 
  address 1: 132.241.5.10 
  address 2: 132.241.5.10 
  內存結構: 
   
   
   
  假如你需要保存這個IP地址,使用strcpy()函數來指向你自己的字符指針。 
  ================================================================== 
  htonl()表示將32位的主機字節順序轉化爲32位的網絡字節順序 htons()表示將16位的主機字節順序轉化爲16位的網絡字節順序(ip地址是32位的端口號是16位的 ) 
  inet_ntoa() 
  簡述: 
  將網絡地址轉換成“.”點隔的字符串格式。 
  #include 
  char FAR* PASCAL FAR inet_ntoa( struct in_addr in); 
  in:一個表示Internet主機地址的結構。 
  註釋: 
  本函數將一個用in參數所表示的Internet地址結構轉換成以“.” 間隔的諸如“a.b.c.d”的字符串形式。請注意inet_ntoa()返回的字符串存放在WINDOWS套接口實現所分配的內存中。應用程序不應假設該內存是如何分配的。在同一個線程的下一個WINDOWS套接口調用前,數據將保證是有效。 
  返回值: 
      若無錯誤發生,inet_ntoa()返回一個字符指針。否則的話,返回NULL。其中的數據應在下一個WINDOWS套接口調用前複製出來。 
  參見: 
  inet_addr(). 
  測試代碼如下 
  include 
  #include 
  #include 
  #include 
  #include 
  int main(int aargc, char* argv[]) 
  { 
  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));    //注意這一句的運行結果 
  printf("%s\n", inet_ntoa(addr1)); 
  printf("%s\n", inet_ntoa(addr2)); 
  return 0; 
  } 
  實際運行結果如下: 
  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裏面靜態分配的,所以inet_ntoa後面的調用會覆蓋上一次的調用。第一句printf的結果只能說明在printf裏面的可變參數的求值是從右到左的,僅此而已。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章