调用socket::connect, socket::bind, socket::listen而不使用getaddrin

Calling socket::connect, socket::bind, socket::listen without using getaddrinfo( ) function before it

本文关键字:socket getaddrin bind connect 调用 listen      更新时间:2023-10-16

在包括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_addrsockaddr类型,可以安全地类型转换为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()

的循环呢?

确保您的值按照网络顺序排列,下面是一个小示例:

#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);
}