文章出處

inet_addr()

 
  簡述:將一個點間隔地址轉換成一個in_addr。
  #include <winsock.h>
  unsigned long PASCAL FAR inet_addr( const struct FAR* cp);
  cp:一個以Internet標準“.”間隔的字符串。
  注釋:
  本函數解釋cp參數中的字符串,這個字符串用Internet的“.”間隔格式表示一個數字的Internet地址。返回值可用作Internet地址。所有Internet地址以網絡字節順序返回(字節從左到右排列)。
  Internet地址用“.”間隔的地址可有下列幾種表達方式:
  a.b.c.d,a.b.c,a.b,a
  當四個部分都有定值時,每個都解釋成一個字節數據,從左到右組成Internet四字節地址。請注意,當一個Internet地址在Intel機器上表示成一個32位整型數時,則上述的字節為“d.c.b.a”。這是因為Intel處理器的字節是從右向左排列的。
  請注意:只有Berkeley支持下述表達法,Internet其余各處均不支持。考慮到與軟件的兼容性,應按規定進行使用。
  對一個三部分地址,最后一部分解釋成16位數據并作為網絡地址的最右兩個字節。這樣,三部分地址便很容易表示B組網絡地址,如“128.net.host”.
  對一個兩部分地址,最后一部分解釋成24位數據并作為網絡地址的最右三個字節,這樣,兩部分地址便很容易表示C組網絡地址,如“net.host”。
  對僅有一個部分的地址,則將它的值直接存入網絡地址不作任何字節的重組。
  返回值:
  若無錯誤發生,inet_addr()返回一個無符號長整型數,其中以適當字節順序存放Internet地址。如果傳入的字符串不是一個合法的Internet地址,如“a.b.c.d”地址中任一項超過255,那么inet_addr()返回INADDR_NONE。
  參見:

  inet_ntoa().

inet_addr()函數的實現

輸入是點分的IP地址格式(如A.B.C.D)的字符串,從該字符串中提取出每一部分,轉換為ULONG,假設得到4個ULONG型的A,B,C,D,
ulAddress(ULONG型)是轉換后的結果,
ulAddress = D<<24 + C<<16 + B<<8 + A(網絡字節序),即inet_addr(const char *)的返回結果
另外,我們也可以得到把該IP轉換為主機序的結果,轉換方法一樣
A<<24 + B<<16 + C<<8 + D

 

 
 
inet_ntoa() 
 
簡述:
 
  將網絡地址轉換成“.”點隔的字符串格式。
 
  #include <winsock.h>
 
  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套接口調用前復制出來。
 
  測試代碼如下
 
  include <stdio.h>
 
  #include <sys/socket.h>
 
  #include <netinet/in.h>
 
  #include <arpa/inet.h>
 
  #include <string.h>
 
  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里面的可變參數的求值是從右到左的,僅此而已。
 
inet_aton()
 
inet_aton是一個改進的方法來將一個字符串IP地址轉換為一個32位的網絡序列IP地址。這個函數的概要如下:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int inet_aton(const char *string, struct in_addr *addr);

inet_aton函數接受兩個參數。參數描述如下:

1 輸入參數string包含ASCII表示的IP地址。
2 輸出參數addr是將要用新的IP地址更新的結構。

如果這個函數成功,函數的返回值非零。如果輸入地址不正確則會返回零。使用這個函數并沒有錯誤碼存放在errno中,所以他的值會被忽略。

對于這個函數有一點迷惑的就是這個函數調用所需要的兩個參數。如果我們定義了一個AF_INET套接口地址:

struct sockaddr_in adr_inet;    /* AF_INET */

提供給inet_aton函數調用的參數指針為 &adr_inet.sin_addr

下面這個程序使用inet_aton函數,而不是我們在前面所談到的in_addr函數。
/*
 * inetaton.c
 *
 * Example using inet_aton
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/*
 * this function reports the error and
 * exits back to the shell
 */
static void bail(const char *on_what)
{
    fputs(on_what,stderr);
    fputs("/n",stderr);
}

int main(int argc,char **argv)
{
    int z;
    struct sockaddr_in adr_inet;    /* AF_INET */
    int len_inet;            /* length */
    int sck_inet;            /* Socket */

    /* Create a Socket */
    sck_inet = socket(AF_INET,SOCK_STREAM,0);

    if(sck_inet == -1)
    bail("Socket()");

    /* Establish address */
    memset(&adr_inet,0,sizeof adr_inet);
    adr_inet.sin_family = AF_INET;
    adr_inet.sin_port = htons(9000);

    if( !inet_aton("127.0.0.1",&adr_inet.sin_addr))
    bail("bad address");

    len_inet = sizeof adr_inet;

    /* Bind it to the socket */
    z = bind(sck_inet,(struct sockaddr *)&adr_inet,len_inet);

    if(z == -1)
    bail("bind()");

    /* Display our socket address */
    system("netstat -pa --tcp 2>/dev/null"
        " | grep inetaton");

    return 0;
}
程序的運行結果如下:
S$ ./inetaton
tcp 0 0 127.0.0.23:9000 *:* CLOSE 1007/inetaton
 

文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()