字符串ipv4和ipv6地址转换成整形

第二类为同时支持IPv4和IPv6。包括,inet_pton和inet_ntop。其定义如下:

#include
int inet_pton(int af, const char* src, void* dst);
//返回:成功返回1;输入格式无效返回0;出错返回-1。
const char* inet_ntop(int af, const void* src, char* dst, socklen_t cnt);
//返回:成功返回指向结果的指针;出错返NULL。
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46

其中各参数的含义如下:

af参数指定地址族。可选为:AF_INET和AF_INET6;

src为转换源,dst为转换目标。这里要注意的是,不能传给inet_ntop一个空指针,必须是一个已分配目标大小内存的指针。

cnt参数指定目标存储单位的大小。上面定义的两个宏可以帮助指定IPv4和IPv6的特定大小。
用法如下:

#include
#include

int main(){
char* ip = “1.2.3.4”;
struct in_addr addr;

int i = 0;
int *ad = &i;
inet_pton(AF_INET, ip, ad);
printf("%d

", *ad);

char ip2[INET_ADDRSTRLEN];
char* ip3 = inet_ntop(AF_INET, ad, ip2, INET_ADDRSTRLEN);
printf("%s

“, ip2);
printf(”%s
", ip3);

return 0;

}


struct sockaddr {
unsigned short sa_family;     /* address family, AF_xxx /
char sa_data[14];  /
14 bytes of protocol address */
};

struct sockaddr_in {
short int sin_family; /* Address family AF_INET /
unsigned short int sin_port;    /
Port number /
struct in_addr sin_addr;   /
Internet address /
unsigned char sin_zero[8];    /
Same size as struct sockaddr /
};

struct in_addr {
unsigned long s_addr;   /
Internet address */
};

struct sockaddr_in6 {
sa_family_t sin6_family;   /* AF_INET6 /
in_port_t sin6_port; /
transport layer port # /
uint32_t sin6_flowinfo;   /
IPv6 traffic class & flow info /
struct in6_addr sin6_addr;     /
IPv6 address /
uint32_t sin6_scope_id;    /
set of interfaces for a scope /
};
struct in6_addr {
uint8_t s6_addr[16];   /
IPv6 address */
};

struct addrinfo{
int ai_flags; /* AI_PASSIVE,AI_CANONNAME,AI_NUMERICHOST /
int ai_family; /
AF_INET,AF_INET6 /
int ai_socktype;   /
SOCK_STREAM,SOCK_DGRAM /
int ai_protocol;   /
IPPROTO_IP, IPPROTO_IPV4, IPPROTO_IPV6 /
size_t ai_addrlen;    /
Length */
char ai_cannoname;       / */
struct sockaddr ai_addr;        / struct sockaddr */
struct addrinfo ai_next;      / pNext */
}


函数原型:

int inet_pton(int af, const char *src, void *dst);
//这个函数转换字符串到网络地址,第一个参数af是地址族,转换后存在dst中 af的值可为AF_INET (代表使用IPv4协议)或AF_INET6(代表作用IPv6协议)

const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
//这个函数转换网络二进制结构到ASCII类型的地址,参数的作用和上面相同,只是多了一个参数socklen_t cnt,
//他是所指向缓存区dst的大小,避免溢出,如果缓存区太小无法存储地址的值,则返回一个空指针,并将errno置为ENOSPC
举例:

#include
#include
#include
#include

int main(int argc, char **argv)
{
unsigned char buf[sizeof(struct in6_addr)];
int domain, s;
char str[INET6_ADDRSTRLEN];

if(argc != 3){     
    fprintf(stderr, "usage: %s {i4|i6|} string/n", argv[0]);     
    exit(EXIT_FAILURE);     
}     
       
domain = (strcmp(argv[1], "i4") == 0) ? AF_INET:(strcmp(argv[1], "i6") == 0) ? AF_INET6 : atoi(argv[1]);     
           
//IP字符串 ——》网络字节流     
s = inet_pton(domain, argv[2], buf);     
if(s<=0){     
    if(0 == s)     
        fprintf(stderr, "Not in presentation format/n");     
    else
        perror("inet_pton");     
    exit(EXIT_FAILURE);     
}     
       
//网络字节流 ——》IP字符串     
if(inet_ntop(domain, buf, str, INET6_ADDRSTRLEN) == NULL){       
    perror("inet ntop/n");     
    exit(EXIT_FAILURE);     
}     
       
printf("%s/n", str);     
exit(EXIT_SUCCESS);     

}

你可能感兴趣的:(网络编程,网络,服务器,linux)