(一)通用socket地址
(1)struct sockaddr
- struct socketaddr类型是网络编程的通用地址类型,其定义如下
头文件:bits/socket.h
#include <bits/socket.h>
struct sockaddr
{
sa_family_t sa_family;
char sa_data[14];
};
- 协议族和地址族的关系
注意:宏PF_*和AF_*都定义在bits/socket.h中,两者的值相同,二者通常混用
sa_data无法容纳大部分协议的地址值,所以产生了(2)
(2)struct sockaddr_storage
头文件:bits/socket.h
#include <bits/socket.h>
struct sockaddr_storage
{
sa_family_t sa_family;
unsigned long int __ssalign;
char __ss_padding[128 - sizeof(__ssalign)];
};
该结构体空间够大,可存放地址值,而且使用__ss_align进行了字节对齐,但都不是很好用!!
由于(1)(2)设置IP地址和端口号都要执行位操作,比较繁琐,所以linux对各个协议提供了专用地址
(二)专用socket地址
(1) UNIX本地域协议族的socket地址结构体
头文件:sys/un.h
#include <sys/un.h>
struct sockaddr_un
{
sa_family_t sin_family;
char sun_path[108];
};
(2)TCP/IP协议族地址结构体
头文件:netinet/in.h
#include <netinet/in.h>
struct sockaddr_in
{
sa_family_t sin_family;
u_int16_t sin_port;
struct in_addr sin_adrr;
};
#include <netinet/in.h>
struct in_addr
{
u_int32_t s_addr;
};
#include <netinet/in.h>
struct sockadrr_in6
{
sa_family_t sin6_family;
u_int16_t sin6_port;
u_int32_t sin6_flowinfo;
struct in6_addr sin6_addr;
u_int32_t sin6_scope_id;
};
#include <netinet/in.h>
struct in6_addr
{
unsigned char sa_addr[16];
};
注意:在使用socket编程接口时,对这两个专用的地址结构体需要强制转换成struct sockaddr类型
(三)IP地址转换函数
一般使用字符串表示IP地址:点分十进制表示IPv4地址,十六进制字符串表示IPv6地址。 编程使用中需要将字符串转成整型数据才能使用;
头文件:arpa/inet.h
(1)将一个点分十进制字符串IP地址转成长整型
in_addr_t inet_addr(const char* strptr);
- strptr :点分十进制的字符串IP地址
- 返回值:成功无符号长整型数。失败返回INADDR_NONE
(2)将一个字符串IP地址转换为一个32位的网络序列IP地址
int inet_aton(const char* cp, struct in_addr* inp);
- cp : 字符串IP地址
- inp : 用来存放转换后的网络序列
- 返回值:成功返回1,IP地址不正确导致失败返回0,不设置errno值
(3)将网络序列IP地址转成点分十进制字符串IP地址
char* inet_ntoa(struct in_addr in);
- in : 网络序列IP地址
- 返回值:成功返回点分十进制的字符串IP地址,失败返回NULL
(4)IP地址转换函数测试代码
#include <arpa/inet.h>
#include <stdio.h>
int main()
{
in_addr_t ret = inet_addr("127.0.0.1");
printf("ret = %d\n", ret);
struct in_addr buff;
if(inet_aton("127.0.0.1", &buff) != 0)
{
printf("buff.s_addr = %d\n", buff.s_addr);
}
char* s = inet_ntoa(buff);
if(s != NULL)
{
printf("s = %s\n", s);
}
return 0;
}
-
结果: -
拓展:
(四)端口转换函数
头文件:arpa/inet.h
(1)主机端口转成网络端口(短整型short 16位)
uint16_t htons(uint16_t hostshort);
(2)主机端口转成网络端口(长整型int 32位)
uint32_t htons(uint32_t hostlong);
(3)网络端口转成主机端口(短整型short 16位)
uint16_t htons(uint16_t netshort);
(4)网络端口转成主机端口(长整型int 32位)
uint16_t htons(uint32_t netlong);
(5)端口转换测试代码
#include <arpa/inet.h>
#include <stdio.h>
int main()
{
uint16_t port_net = htons(6000);
printf("网络端口port_net = %d\n", port_net);
uint16_t port_short = ntohs(port_net);
printf("主机端口port_short = %d\n", port_short);
return 0;
}
- 结果:
|