在包括Beej's Guide的所有示例中,IP地址以点表示法提供,然后将其提供给::getaddrinfo()
。 This post没有回答我的问题。
之后,addrinfo
结构用于套接字相关函数(例如connect()
,bind()
,listen()
)。例如:
struct addrinfo hints, *res;
// ... create socket etc.
connect(sockfd, res->ai_addr, res->ai_addrlen);
Example
变量ai_addr
的类型为sockaddr
,可以安全对sockaddr_storage
,sockaddr_in
和sockaddr_in6
进行类型转换。
问题:
如果我将sockaddr
强加给sockaddr_in
(或sockaddr_in6
)
sockaddr_in& ipv4 = (sockaddr_in&)(sockaddr_variable);
并提供以下信息:
我可以直接使用上述信息调用connect()
方法吗?
connect(sockfd, &ipv4, sizeof(ipv4));
使用我的程序它似乎不起作用。我错过了什么,还是有更好的方法?
背后的动机是,如果我们以套接字可读格式获得IPAddress,Port等的信息,那么为什么要经历getaddrinfo()
的循环
答案 0 :(得分:2)
请确保您将值放在网络顺序中,这是一个小例子:
#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 socket\n");
}
printf("Socket created\n");
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("Connected\n");
close(sock);
return 0;
}
答案 1 :(得分:0)
首先检查机器是否可以到达&amp;服务器应用程序正在使用“netstat”实用程序在计算机上运行。使用inet_aton方法将虚线地址转换为网络字节顺序。最后,记录connect返回的错误值,以获得失败的确切原因。
答案 2 :(得分:0)
值得注意的是,调用socket::{connect, bind, ...}
是错误的:这些是C API
并且C没有名称空间,类等等。
您应该使用getaddrinfo
,因为它使用起来更容易,更安全。但没有什么能阻止你使用struct sockaddr
及其所有变体。实际上,getaddrinfo
是man(3) getaddrinfo
中所述的一种包装:
getaddrinfo()函数结合了这些功能 由gethostbyname(3)和getservbyname(3)函数提供 单个接口,但与后面的函数不同,getaddrinfo()是 可重入并允许程序消除IPv4与IPv6的相关性 - CIES。
一个例子:
#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);
}