Technorati 标签: socket

在这里http://www.cppblog.com/izualzhy/archive/2012/07/28/185459.html介绍了两个结构体

struct sockaddr与struct sockaddr_in的关系和区别。

其中struct sockaddr_in有一个成员为

struct in_addr sin_addr;//Internet地址

原文里关于该结构体做了足够的说明:

而struct in_addr的定义如下(unix):
typedef uint32_t in_addr_t;

struct in_addr {

in_addr_t s_addr;

};

那么该结构体到底如何使用的?该如何赋值?

这里就用得到inet_addr()了,该函数用于将形如”192.168.1.1”的ip地址字符串转化为

in_addr_t的形式(实际上就是uint32_t,即unsigned long).

例如192对应的16进制为c0,168(a8).

逆过程则用inet_ntoa实现。

直接看个例子和运行结果,一目了然~

/*
 * =====================================================================================
 *       Filename:  test.c
 *    Description:  sample of inet_ntoa,inet_addr 
 *        Created:  08/04/2012 01:23:39 PM
 *         Author:  zhy (), [email protected]
 * =====================================================================================
 */
#include <stdio.h>
#include <netinet/in.h>

int main()
{
    struct in_addr addr;
    char* straddr = malloc(16*sizeof(char));
    memset(straddr, 0, 16);

    addr.s_addr = inet_addr("192.168.1.1");
    printf("%x\n",addr.s_addr);
    printf("%s\n",inet_ntoa(addr));

    addr.s_addr = inet_addr("172.27.1.1");
    printf("%x\n",addr.s_addr);
    printf("%s\n",inet_ntoa(addr));

    addr.s_addr = inet_addr("255.255.255.255");
    printf("%x, %d\n",addr.s_addr,addr.s_addr);
    printf("%s\n",inet_ntoa(addr));

    return 0;
}

结果:

y@y-VirtualBox:/mnt/Documents/Training$ ./test
101a8c0
192.168.1.1
1011bac
172.27.1.1
ffffffff, -1
255.255.255.255

同时可以注意到:

inet_addr()返回的地址已经是网络字节格式,所以你无需再调用 函数htonl()。
我们现在发现上面的代码片断不是十分完整的,因为它没有错误检查。 显而易见,当inet_addr()发生错误时返回-1。记住这些二进制数字?(无符 号数)-1仅仅和IP地址255.255.255.255相符合!这可是广播地址!大错特 错!记住要先进行错误检查。

而inet_adder的manpage里也提到了:

The inet_addr() function converts the Internet  host  address  cp  from
IPv4  numbers-and-dots notation into binary data in network byte order.
If the input is invalid, INADDR_NONE (usually -1) is returned.  Use  of
this   function   is   problematic   because  -1  is  a  valid  address
(255.255.255.255).   Avoid   its   use   in   favor   of   inet_aton(),
inet_pton(3), or getaddrinfo(3) which provide a cleaner way to indicate
error return.

ps:
我这里比较好奇的是,inet_ntoa返回一个char*而外部可以直接使用又不需要free,是如何做到的?