在包括Beej's Guide在内的所有示例中,IP地址都以点表示法提供,然后将其馈送给::getaddrinfo()
。这篇文章没有回答我的问题。
之后,addrinfo
结构体用于套接字相关的函数(例如connect()
, bind()
, listen()
)。例如:
struct addrinfo hints, *res;
// ... create socket etc.
connect(sockfd, res->ai_addr, res->ai_addrlen);
例子变量ai_addr
为sockaddr
类型,可以安全地类型转换为sockaddr_storage
、sockaddr_in
和sockaddr_in6
。
:
如果我将sockaddr
类型转换为sockaddr_in
(或sockaddr_in6
)
sockaddr_in& ipv4 = (sockaddr_in&)(sockaddr_variable);
和饲料下面的信息:
- ipv4。sin_family = AF_INET
- ipv4。sin_addr = [IP地址的字节顺序]
- ipv4。sin_port =[端口号的字节顺序]
我可以直接使用上面的信息调用connect()
方法吗?
connect(sockfd, &ipv4, sizeof(ipv4));
在我的程序中,它似乎不起作用。是我错过了什么,还是有更好的方法?
背后的动机是,如果我们有套接字可读格式的IPAddress, Port等信息,那么为什么要经历getaddrinfo()
确保您的值按照网络顺序排列,下面是一个小示例:
#include<stdio.h>
#include<sys/socket.h>
#include<arpa/inet.h>
int main(int argc, char *argv[])
{
int sock;
struct sockaddr_in server;
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1)
{
printf("Could not create socketn");
}
printf("Socket createdn");
server.sin_family = AF_INET;
// 173.194.32.207 is a google address
server.sin_addr.s_addr = 173 | 194 << 8 | 32 << 16 | 207 << 24;
server.sin_port = 0x5000; // port 80
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0)
{
perror("connect failed. Error");
return 1;
}
printf("Connectedn");
close(sock);
return 0;
}
首先检查机器是否可达;服务器应用程序使用"netstat"实用程序在机器上运行。使用inet_aton方法将点地址转换为网络字节顺序。最后,记录连接返回的错误值,以获得失败的确切原因。
值得注意的是,调用socket::{connect, bind, ...}
是错误的:这些是C API
s, C没有名称空间、类等。
你应该使用getaddrinfo
,因为它更容易和安全使用。但是没有什么可以阻止您使用struct sockaddr
及其所有变体。实际上,getaddrinfo
是一种包装器,如man(3) getaddrinfo
:
getaddrinfo()函数组合了这些功能由gethostbyname(3)和getservbyname(3)函数提供getaddrinfo()是单一接口,但与后面的函数不同可重入,并允许程序消除ipv4与ipv6的依赖私事。
一个例子:
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main()
{
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
inet_pton(addr.sin_family, "198.252.206.16", &addr.sin_addr);
int fd = socket(addr.sin_family, SOCK_STREAM, 0);
if (fd == -1)
; /* could not create socket */
if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
; /* could not connect */
close(fd);
}