博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
网络编程中常见地址结构与转换(IPv4/IPv6)
阅读量:5113 次
发布时间:2019-06-13

本文共 3319 字,大约阅读时间需要 11 分钟。

1. sockaddr/sockaddr_in/in_addr (IPv4)、sockaddr6_in/in6_addr/addrinfo (IPv6)

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 */ 
};  <br>
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 */ 

2. 与IP地址相关的常用网络编程函数

2.1 地址转化函数

IPv4中,可使用inet_ntoa/inet_aton来转化字符串形式表示的IPv4地址和数字形式表示的IPv4地址。此两函数不适用于IPv6地址转换。在Linux环境下使用inet_ntoa/inet_atoa时,需加头文件:

#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

函数原型:

int 
inet_aton(
const 
char 
* cp,
struct 
in_addr *inp);
char 
* inet_ntoa(
struct 
in_addr
in
);

举例:

#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;
    
ulong 
l1;
    
l1 = inet_addr(
"192.168.0.74"
);
    
memcpy(&addr1, &l1,
sizeof
(l1));
    
printf(
"%s\n"
, inet_ntoa(addr1));
  
if
(inet_aton(
"127.0.0.1"
, &addr1)){
    printf(
"inet_aton:ip=%lu\n"
,ntohl(inp.s_addr));
   }
  
else
{
    printf(
"inet_aton return -1 when 255.255.255.255\n"
);
   }
  
return 
0;
}

IPv6中,使用inet_ntop/inet_pton来转化字符串形式表示的IPv6地址和数字形式表示的IPv6地址。IPv4中也可使用这两个函数。

函数原型:

int 
inet_pton(
int 
af,
const 
char 
*src,
void 
*dst);         <br>
//这个函数转换字符串到网络地址,第一个参数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 <stdio.h>    
#include <stdlib.h>    
#include <string.h>    
#include <arpa/inet.h>    
           
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|<num>} 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);    
}

转载于:https://www.cnblogs.com/wuyuxuan/p/10772792.html

你可能感兴趣的文章
Ubuntu下安装MySQL及简单操作
查看>>
前端监控
查看>>
clipboard.js使用方法
查看>>
移动开发平台-应用之星app制作教程
查看>>
leetcode 459. 重复的子字符串(Repeated Substring Pattern)
查看>>
伪类与超链接
查看>>
centos 7 redis-4.0.11 主从
查看>>
博弈论 从懵逼到入门 详解
查看>>
永远的动漫,梦想在,就有远方
查看>>
springboot No Identifier specified for entity的解决办法
查看>>
慵懒中长大的人,只会挨生活留下的耳光
查看>>
"远程桌面连接--“发生身份验证错误。要求的函数不受支持
查看>>
【BZOJ1565】 植物大战僵尸
查看>>
VALSE2019总结(4)-主题报告
查看>>
浅谈 unix, linux, ios, android 区别和联系
查看>>
51nod 1428 活动安排问题 (贪心+优先队列)
查看>>
中国烧鹅系列:利用烧鹅自动执行SD卡上的自定义程序(含视频)
查看>>
Solaris11修改主机名
查看>>
latex for wordpress(一)
查看>>
如何在maven工程中加载oracle驱动
查看>>