(3)深入浅出IP地址

深入浅出IP地址

socket参数详解

  • 函数原型:int socket(int domain, int type, int protocal);
参数意义
domain套接字中使用的协议簇信息
type套接字数据传输类型信息
protoool设备间通信使用的协议信息
  • domain参数(协议簇)
参数协议簇
PF_INETIPv4
PF_INT6IPv6
PF_LOCAL本地(进程间)通信
PF_PACKET底层数据收发
PF_IPXNovell专用协议(互联网分组交换协议)
  • type参数:用于指定协议类型
    SOCK_STREAM : 流式数据(TCP)
    SOCK_UGRAM : 报文式数据(UDP)
  • protocol参数 : 用于指定协议簇中符合类型的具体协议
    domain和type几乎可以唯一确定一种协议,因此,这个参数通常为0;
    – 即:0代表domain和type指定后的默认协议。
  • Eg:socket(PF_INET,SOCK_STREAM,0);//代表使用基于IPv4的TCP协议

关于端口号和IP地址

  • IP地址是一个4字节地址(可分为5类),端口号是一个2字节数据;
  • 0~1023作为特定端口被预定义(分配给特定应用程序);

深入解析IP地址

  • IP地址分为网路标识主机标识两部分;
    网路标识:标识网络主机所在的网络;
    主机标识:标识网络主机的具体地址;
  • IP地址子网掩码配合使用用于区分网络标识主机标识
  • 子网掩码的表现形式也是一个4字节的整型数
  • 子网掩码用于从IP地址中提取网络标识;
  • 特殊地址:
    – 0.0.0.0/0 :保留,常用于代表”缺省地址“;
    – 127.0.0.0/8 : 回环地址,常用于本地软件回送测试;
    – 255.255.255.255/32 :广播地址。
  • 私有地址:不在公网使用,只在内网使用
    – 10.0.0.0/8 ~10.255.255.255/8
    – 172.16.0.0/16 ~ 172.31.255.255/16
    – 192.168.0.0/24 ~ 192.168.255.255/24

网络编程中的地址类型

sock = socket(PF_INET,SOCK_STREAM,0);//为网络连接做准备,失败时返回-1
if(sock == -1)
{
	printf("socket error\n");
	return -1;
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("47.99.217.175");//指定IP地址
addr.sin_port = htons(80);//指定端口号
if(connect(sock,(struct sockaddr*)&addr,sizeof(addr)) == -1)//连接失败时,返回-1
{
	printf("connect error\n");
	return -1;
}
len = send(sock,tosend,strlen(tosend),0);//连接成功后,开始发送数据,返回值为成功发送数据的长度
printf("send bytes = %d\n",len);
len = recv(sock,buf,sizeof(buf),0);//开始接收数据,返回值为成功接收到数据的长度
printf("receive bytes = %d\n",len);
  • AF_INET和PF_INET的区别: AF_INET代表的是IPv4地址(地址类型),PF_INET代表的是IPv4协议(协议类型);
  • 地址数据类型解析:
struct in_addr
{
	u_int32_t s_addr;
};

//地址父类
struct sockaddr
{
	sa_family_t sa_family;
	char sa_data[14];
}

//IPv4
struct sockaddr_in
{
	sa_family_t sa_family;
	u_int16_t sin_port;
	struct in_addr sin_addr;
}

//local
struct sockaddr_un
{
	sa_famliy_t sa_family;
	....
}

//IPv6
struct sockaddr_in6
{
	sa_famliy_t sa_family;
	....
}

socket函数支持多种不同的通信协议,每种通信协议都有一个特定的结构体,通过sa_family来判断当前使用的协议。

  • IP地址相关函数
    #include<arpa/inet.h>
函数原型功能描述
in_addr_t inet_addr(const char* strptr);将IP字符串转换为符合网络字节序的整数
int inet_aton(const char* cp, struct in_addr* inp);将IP字符串转换为符合网络字节序的整数,成功返回1,失败返回0
char* inet_ntoa(struct in_addr in);将符合网络字节序的整数地址转换为字符串形式

当无法确认得到的IP字符串是否合法时,使用inet_aton函数,而不是inet_addr函数;

  • 代码示例
unsigned int addr = inet_addr("1.2.3.4");
struct in_addr addr1 = {0x09080706};
struct in_addr addr2 = {0x05040302};

#if 0//inet_ntoa函数不能这么使用
	char* s1 = inet_ntoa(addr1);
	char* s2 = inet_ntoa(addr2);
#else
	char* s1 = strcpy(malloc(32), inet_ntoa(addr1));
	char* s2 = strcpy(malloc(32), inet_ntoa(addr2));
#endif

printf("addr = %x\n",addr);
printf("s1 = %s\n",s1);
printf("s2 = %s\n",s2);

//可用于判断IP地址是否合法
if(inet_aton("4.3.2.1",&addr1))
{
	printf("addr1 = %x\n",addr1.s_addr);
}

free(s1);
free(s2);
  • inet_ntoa每次被调用都会把先处理结果放在同一片内存中,再返回这片内存的地址,所以直接多次调用的话,新的会覆盖旧的;所以当需要多次使用时,每次使用后都需要把结果先读出;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值