首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从sockaddr_in / sockaddr_in6结构创建sockaddr

如何从sockaddr_in / sockaddr_in6结构创建sockaddr
EN

Stack Overflow用户
提问于 2019-09-04 08:39:53
回答 2查看 3.7K关注 0票数 0

下面是IPv6和IPv4 clinet代码示例代码的摘录:

IPv6

代码语言:javascript
运行
复制
int s;
struct sockaddr_in6 addr;

s = socket(AF_INET6, SOCK_STREAM, 0);
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(5000);
inet_pton(AF_INET6, "::1", &addr.sin6_addr);
connect(s, (struct sockaddr *)&addr, sizeof(addr));

IPv4

代码语言:javascript
运行
复制
int s;
struct sockaddr_in addr;

s = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(5000);
servaddr.sin_addr.s_addr = INADDR_ANY; 
connect(s, (struct sockaddr *)&addr, sizeof(addr));

我的目标是为IPv6和IPv4地址编写一个用户定义的连接API。由于它们都将结构转换为sockaddr结构--以编程的方式--如何将sockaddr_insockaddr_in6转换为 sockaddr 结构(填充其成员变量),然后调用连接sockaddr sturcure?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-09-04 21:33:11

在编程上,我们如何将sockaddr_insockaddr_in6转换为sockaddr结构(填充其成员变量),然后用sockaddr结构调用connect?

类型转换不是转换。你不能改变任何事。正如您提供的示例所示,您根据需要创建了一个sockaddr_insockaddr_in6实例,然后将其作为-is传递给connect()。您只是在键入指向struct实例的指针。在内部,connect()将查看其输入addrsa_family字段,并相应地将addr类型转换回sockaddr_insockaddr_in6,以便根据需要访问数据字段。

我的目标是为IPv6和IPv4地址编写一个用户定义的连接API。

如果您想编写与协议无关的代码,您可以这样做:

代码语言:javascript
运行
复制
int doConnect(int family, const char *ip, u_short port)
{
    struct sockaddr_storage ss = {};
    socklen_t addrlen;

    switch (family)
    {
        case AF_INET:
        {
            struct sockaddr_in *addr = (struct sockaddr_in *) &ss;
            addr->sin_family = AF_INET;
            addr->sin_port = htons(port);
            inet_pton(AF_INET, ip, &addr->sin_addr);
            addrlen = sizeof(struct sockaddr_in);
            break;
        }

        case AF_INET6:
        {
            struct sockaddr_in6 *addr = (struct sockaddr_in6 *) &ss;
            addr->sin6_family = AF_INET6;
            addr->sin6_port = htons(port);
            inet_pton(AF_INET6, ip, &addr->sin6_addr);
            addrlen = sizeof(struct sockaddr_in6);
            break;
        }

        default:
            return -1;
    }

    int s = socket(family, SOCK_STREAM_IPPROTO_TCP);
    if (s != -1)
    {
        if (connect(s, (struct sockaddr *) &ss, addrlen) < 0)
        {
            close(s);
            s = -1;
        }
    }

    return s;
}
代码语言:javascript
运行
复制
int s = doConnect(AF_INET, "127.0.0.1", 5000);
代码语言:javascript
运行
复制
int s = doConnect(AF_INET6, "::1", 5000);

然而,更好的解决方案是使用getaddrinfo(),让它根据实际解析的输入值为您分配正确的sockaddr数据,例如:

代码语言:javascript
运行
复制
int doConnect(const char *ip, u_short port)
{
    struct addrinfo hints = {};
    hints.ai_flags = AI_NUMERICHOST;
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    struct addrinfo *addr;

    char szPort[6];
    sprintf(szPort, "%hu", port);

    int s = -1;

    int ret = getaddrinfo(ip, szPort, &hints, &addr);
    if (ret == 0)
    {
        s = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
        if (s != -1)
        {
            if (connect(s, addr->ai_addr, addr->ai_addrlen) == -1)
            {
                close(s);
                s = -1;
            }
        }

        freeaddrinfo(addr);
    }

    return s;
}
代码语言:javascript
运行
复制
int s = doConnect("127.0.0.1", 5000);
代码语言:javascript
运行
复制
int s = doConnect("::1", 5000);

getaddrinfo()的好处在于,您也可以将它用于服务器。只需在AI_PASSIVE字段中使用hints.ai_flags标志,然后使用生成的addrinfo项调用socket()bind()

票数 2
EN

Stack Overflow用户

发布于 2019-09-04 09:45:21

如何在编程上将sockaddr_insockaddr_in6转换为sockaddr

您不能这样做,因为sockaddr_insockaddr_in6都不能保证适合sockaddr结构。

structure

<sys/socket.h>标头应定义sockaddr_storage结构,该结构应为:

  • 大到足以容纳所有支持的协议特定的地址结构。
  • 在适当的边界上对齐,以便可以将指向它的指针转换为指向特定于协议的地址结构的指针,并用于访问这些结构的字段,而不存在对齐问题。

sockaddr_storage结构至少应包括下列成员:

sa_family_t ss_family

当指向sockaddr_storage结构的指针被转换为指向sockaddr结构的指针时,sockaddr_storage结构的ss_family字段将映射到sockaddr结构的sa_family字段。当指向sockaddr_storage结构的指针转换为指向特定于协议的地址结构的指针时,ss_family字段将映射到该结构的字段上,该字段的类型为sa_family_t并标识该协议的地址族。

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

https://stackoverflow.com/questions/57784632

复制
相关文章

相似问题

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