您好,欢迎来到爱玩科技网。
搜索
您的当前位置:首页地址转换函数:inet_aton & inet_ntoa & inet_addr和inet_pton & inet_ntop

地址转换函数:inet_aton & inet_ntoa & inet_addr和inet_pton & inet_ntop

来源:爱玩科技网

 

 1 #include<arpa/inet.h>
 2 
 3 /* 返回1:串有效,返回0:串出错 */
 4 int inet_aton(const char *strptr, struct in_addr *addrptr);
 5 
 6 /* 若成功,返回32位二进制的网络字节序地址;若出错,返回INADDR_NONE */
 7 in_addr_t inet_addr(const char *strptr);
 8 
 9 /* 返回指向点分十进制数串的指针 */
10 char* inet_ntoa(struct in_addr inaddr);

  inet_aton将strptr所指的C字符转换为32位网络字节序二进制值,并用一个出参addrptr来存储,返回值为1代表成功,否则返回0。

  

1 #include<arpa/inet.h>
2 
3 /* 若函数成功,则返回1;若输入不是有效的格式,则函数返回0;若处理失败,函数返回-1 */
4 int inet_pton(int family, const char *strptr, void *addrptr);
5 
6 /* 若函数处理成功,返回指向结果的指针;若函数处理失败,返回NULL */
7 const char* inet_ntop(int family, const void *addrptr, char *strptr, size_t len);

  第一个函数转换由指针strptr所指的串,通过指针addrptr存储二进制结果,如果成功,则返回值为1;如果对于指定的family输入串不是有效的表达格式,则返回值为0.

  inet_ntop进行相反的转换,即从数值格式(addrptr)到表达格式(strptr)进行转换。参数len是目标的大小,以免函数溢出其调用者的缓冲区。为有助于规定这个大小,在头文件<netinet/in.h>中有如下定义:

  

1 #define INET_ADDRSTRLEN 16     /* for IPv4 dotted-decimal */
2 #define INET6_ADDRSTRLEN 46   /* for IPv6 hex string */

  如果len太小,无法容纳表达格式结果(包括终止的空字符),则返回一个空指针,并置errno为ENOSPC。

  函数inet_ntop的参数strptr可不能是个空指针,调用者必须为目标分配内存指定大小。成功时,此指针即函数的返回值。

 

1、htonl ()和ntohl( )

u_long PASCAL FAR ntohl (u_long netlong);

u_short PASCAL FAR ntohs (u_short netshort);

ntohl( )-----网络顺序转换成主机顺序

u_long PASCAL FAR htonl (u_long hostlong);

u_short PASCAL FAR htons (u_short hostshort);

htonl ()-----主机顺序转换成网络顺序

2、inet_addr( )和inet_ntoa ( )

unsigned long PASCAL FAR inet_addr (const char FAR * cp);

char FAR * PASCAL FAR inet_ntoa (struct in_addr in);

sockaddr_in , sockaddr , in_addr区别

填值的时候使用sockaddr_in结构,而作为函数(如socket, listen, bind等)的参数传入的时候转换成sockaddr结构就行了,毕竟都是16个字符长。

通常的用法是:  
  int   sockfd;  
  struct   sockaddr_in   my_addr;  
  sockfd   =   socket(AF_INET,   SOCK_STREAM,   0);     
   
  my_addr.sin_family   =   AF_INET;     
  my_addr.sin_port   =   htons(MYPORT);     
  my_addr.sin_addr.s_addr   =   inet_addr("192.168.0.1");  
   
  bzero(&(my_addr.sin_zero),   8);     
    
  bind(sockfd,   (struct   sockaddr   *)&my_addr,   sizeof(struct   sockaddr));

可以用C++做个不太准确的假设。  
sockaddr是base   class    
sockaddr_in   等是derived   class  
如此一来,bind,   connect   ,   sendto   ,   recvfrom等函数就可以使用base class  
来处理多种不同的derived   class了。  
但是实际上,这是没有继承关系(C嘛),所以需要强制造型来转换数据类型。正因为如此,在sendto的时候需要给出len长度,因为不同的sockaddr_xx实现长度并不相同。

名词解析:

主机字节序:

网络字节序:

网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。

为了进行转换bsd socket提供了转换的函数,有下面四个网络与主机字节转换函数:htons ntohs htonl ntohl (s 就是short l是long h是host n是network)

htons 把unsigned short类型从主机序转换到网络序,htonl 把unsigned long类型从主机序转换到网络序,ntohs 把unsigned short类型从网络序转换到主机序,ntohl 把unsigned long类型从网络序转换到主机序。

在使用little endian的系统中 这些函数会把字节序进行转换 在使用big endian类型的系统中这些函数会定义成空宏。

参考资料:

 

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- aiwanbo.com 版权所有 赣ICP备2024042808号-3

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务