首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >调用套接字::connect,socket::bind,socket::侦听而不使用前面的getaddrinfo( )函数

调用套接字::connect,socket::bind,socket::侦听而不使用前面的getaddrinfo( )函数
EN

Stack Overflow用户
提问于 2014-08-09 16:12:40
回答 3查看 1.5K关注 0票数 0

在包括Beej指南在内的所有示例中,IP地址都是以点表示法提供的,然后提供给::getaddrinfo()这个职位不回答我的问题。

之后,addrinfo结构用于与套接字相关的函数(例如connect()bind()listen())。例如:

代码语言:javascript
运行
复制
struct addrinfo hints, *res;
// ... create socket etc.
connect(sockfd, res->ai_addr, res->ai_addrlen);

示例

变量ai_addr的类型为sockaddr,可以安全地向sockaddr_storagesockaddr_insockaddr_in6输入。

问题

如果我将sockaddr类型为sockaddr_in (或sockaddr_in6)

代码语言:javascript
运行
复制
sockaddr_in& ipv4 = (sockaddr_in&)(sockaddr_variable);

并提供以下信息:

  • ipv4.sin_family = AF_INET
  • ipv4.sin_addr =按净字节顺序排列的IP地址
  • ipv4.sin_port =按净字节顺序排列的端口号

我可以直接使用上面的信息调用connect() 方法吗?

代码语言:javascript
运行
复制
connect(sockfd, &ipv4, sizeof(ipv4));

用我的程序,它似乎不起作用。我是错过了什么,还是有更好的方法?

其背后的动机是,如果我们以套接字可读的格式获得IPAddress、端口等信息,那么为什么要经历getaddrinfo()的循环?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-08-09 16:41:56

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

代码语言:javascript
运行
复制
#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;
}
票数 2
EN

Stack Overflow用户

发布于 2014-08-09 17:20:01

首先,检查机器是否可访问&服务器应用程序正在使用"netstat“实用程序在机器上运行。使用inet_aton方法将虚位地址转换为网络字节顺序。最后,记录连接返回的错误值,以获得故障的确切原因。

票数 0
EN

Stack Overflow用户

发布于 2014-08-09 17:39:42

值得注意的是,调用socket::{connect, bind, ...}是错误的:这些是C APIs,C没有名称空间、类等等。

您应该使用getaddrinfo,因为使用它更容易,也更安全。但是,没有什么可以阻止您使用struct sockaddr及其所有变体。实际上,getaddrinfo是一种包装器,如man(3) getaddrinfo中所述。

getaddrinfo()函数将gethostbyname(3)和getservbyname(3)函数提供的功能组合到一个接口中,但与后面的函数不同,getaddrinfo()是可重入的,允许程序消除IPv6 4与IPv6 6的依赖关系。

举个例子:

代码语言:javascript
运行
复制
#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);

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25220512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档