在进行socket编程时,如何填充sockaddr成为关键。
- 方法一 使用getaddrinfo函数进行一步填充
getaddrinfo函数的使用依赖于地址信息结构体addrinfo,这个函数包含在头文件netdb.h中,addrinfo结构体的源码如下,
struct addrinfo {
int ai_flags; /* customize behavior */
int ai_family; /* address family */
int ai_socktype; /* socket type */
int ai_protocol; /* protocol */
socklen_t ai_addrlen; /* length in bytes of address */
struct sockaddr *ai_addr; /* address */
char *ai_canonname; /* canonical name of host */
struct addrinfo *ai_next; /* next in list */
};
创建两个sddrinfo结构体实例hints和pInfos,先手动往hints中填入address family、type和protocol;将点分十进制的ip地址和char型的端口号以及两个addrinfo一并传入getaddrinfo,在getaddrinfo中,以hints为模板,把地址信息填充到pInfos中,pInfos的成员ai_addr即是我们期望的产品。
一个可能的demo如下
int ptonet(const char *ip_address, int port,sockaddr &_addr) {
struct addrinfo hints = { 0 }, *pInfos = 0;
hints.ai_family = AF_INET;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_socktype = SOCK_STREAM;
char port_buf[22];
snprintf(port_buf,22,"%d", port);
int rc = getaddrinfo(ip_address, port_buf, &hints, &pInfos);
_addr = *(pInfos->ai_addr);
return 0;
}
- 方法二 使用inet_pton()函数将点分十进制的ip地址转化成二进制形式,再填充,使用该函数应该包含netinet/in.h和arpa/inet.h头文件。一个可能的demo如下
//fill the sockaddr
sockaddr_in ser_addr;
ser_addr.sin_port = htons(59937);
ser_addr.sin_family = AF_INET;
unsigned int ip_buf;
inet_pton(AF_INET, "172.16.0.6",&ip_buf);
ser_addr.sin_addr.s_addr = ip_buf;