调用socket :: connect,socket :: bind,socket :: listen而不使用getaddrinfo()函数

时间:2014-08-09 16:12:40

标签: c++ sockets getaddrinfo endianness

在包括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_storagesockaddr_insockaddr_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()的循环

3 个答案:

答案 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及其所有变体。实际上,getaddrinfoman(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);

}