Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我是否可以使用inet\u pton为我的TCP套接字服务器设置文本地址,如;“设备1.本地”吗;?_C_Sockets_Tcp_Dns - Fatal编程技术网

我是否可以使用inet\u pton为我的TCP套接字服务器设置文本地址,如;“设备1.本地”吗;?

我是否可以使用inet\u pton为我的TCP套接字服务器设置文本地址,如;“设备1.本地”吗;?,c,sockets,tcp,dns,C,Sockets,Tcp,Dns,我已经用C编写了一个TCP套接字,它需要与通过本地网络连接到此地址的移动应用程序配合使用:“device1.local:6666” 我找到的每个使用inet\u pton()设置服务器地址的示例都有一个类似以下内容的IPV4地址:192.168.1.34,或者一个类似以下内容的IPV6地址:2001:db8:8714:3a90::12。如果我想让客户端远程登录到“device1.local”而不是数字或十六进制地址,我应该指定哪种格式?如何设置TCP套接字服务器以应答该地址 这不起作用: loc

我已经用C编写了一个TCP套接字,它需要与通过本地网络连接到此地址的移动应用程序配合使用:“
device1.local:6666

我找到的每个使用
inet\u pton()
设置服务器地址的示例都有一个类似以下内容的IPV4地址:
192.168.1.34
,或者一个类似以下内容的IPV6地址:
2001:db8:8714:3a90::12
。如果我想让客户端远程登录到“
device1.local
”而不是数字或十六进制地址,我应该指定哪种格式?如何设置TCP套接字服务器以应答该地址

这不起作用:

local_socket = socket(AF_INET6, SOCK_STREAM, 0);
if(local_socket < 0) {
    printf("unable to create socket\n");
    return false;
}
printf("socket created\n");

bzero((void *)&server_address, sizeof(server_address));
server_address.sin6_family = AF_INET6;
int s_code = inet_pton(AF_INET6, "device1.local", &server_address.sin6_addr);
server_address.sin6_port = htons(port_number);

printf("inet_pton returned: %d\n", s_code);

char str[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &server_address.sin6_addr, str, INET6_ADDRSTRLEN);
printf("address from inet_ntop(): %s\n", str);
我意识到我可能对互联网(或本地网络)的工作方式缺乏基本的了解。任何相关的链接,你可以给我,让我可以了解更多关于如何自定义文本地址的工作将不胜感激

如果我想让我的客户端远程登录到“device1.local”而不是数字或十六进制地址,我应该指定哪种格式

inet\u pton()。您不能使用它将主机名解析为IP地址。为此,您需要使用
gethostbyname()
(不推荐使用)或
getaddrinfo()
(首选)

下面是一个
gethostbyname()
示例:

int connect_to_addr(const sockaddr *addr, int addrlen)
{
    local_socket = socket(addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
    if (local_socket == -1)
    {
        printf("unable to create socket\n");
        return -1;
    }

    char str[INET6_ADDRSTRLEN];
    unsigned short port;

    switch (addr->sa_family)
    {
        case AF_INET:
        {
            struct sockaddr_in *saddr = (struct sockaddr_in*)addr;
            inet_ntop(AF_INET, &(saddr->sin6_addr), str, sizeof(str));
            port = ntohs(saddr->sin_port);
            break;
        }

        case AF_INET6:
        {
            struct sockaddr_in6 *saddr = (struct sockaddr_in6*)addr;
            inet_ntop(AF_INET6, &(saddr->sin6_addr), str, sizeof(str));
            port = ntohs(saddr->sin6_port);
            break;
        }
    }

    printf("connecting to address: %s on port: %hu\n", str, port);

    if (connect(local_socket, addr, addrlen) != 0)
    {
        printf("unable to connect\n");

        close(local_socket);
        local_socket = -1;

        return 0;
    }

    printf("connected\n");
    return 1;
}
int connect_to_addr(const sockaddr *addr, int addrlen)
{
    local_socket = socket(addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
    if (local_socket == -1)
    {
        printf("unable to create socket\n");
        return -1;
    }

    char str[INET6_ADDRSTRLEN];
    unsigned short port;

    switch (addr->sa_family)
    {
        case AF_INET:
        {
            struct sockaddr_in *saddr = (struct sockaddr_in*)addr;
            inet_ntop(AF_INET, &(saddr->sin6_addr), str, sizeof(str));
            port = ntohs(saddr->sin_port);
            break;
        }

        case AF_INET6:
        {
            struct sockaddr_in6 *saddr = (struct sockaddr_in6*)addr;
            inet_ntop(AF_INET6, &(saddr->sin6_addr), str, sizeof(str));
            port = ntohs(saddr->sin6_port);
            break;
        }
    }

    printf("connecting to address: %s on port: %hu\n", str, port);

    if (connect(local_socket, addr, addrlen) != 0)
    {
        printf("unable to connect\n");

        close(local_socket);
        local_socket = -1;

        return 0;
    }

    printf("connected\n");
    return 1;
}

下面是一个
getaddrinfo()
示例:

int connect_to_addr(const sockaddr *addr, int addrlen)
{
    local_socket = socket(addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
    if (local_socket == -1)
    {
        printf("unable to create socket\n");
        return -1;
    }

    char str[INET6_ADDRSTRLEN];
    unsigned short port;

    switch (addr->sa_family)
    {
        case AF_INET:
        {
            struct sockaddr_in *saddr = (struct sockaddr_in*)addr;
            inet_ntop(AF_INET, &(saddr->sin6_addr), str, sizeof(str));
            port = ntohs(saddr->sin_port);
            break;
        }

        case AF_INET6:
        {
            struct sockaddr_in6 *saddr = (struct sockaddr_in6*)addr;
            inet_ntop(AF_INET6, &(saddr->sin6_addr), str, sizeof(str));
            port = ntohs(saddr->sin6_port);
            break;
        }
    }

    printf("connecting to address: %s on port: %hu\n", str, port);

    if (connect(local_socket, addr, addrlen) != 0)
    {
        printf("unable to connect\n");

        close(local_socket);
        local_socket = -1;

        return 0;
    }

    printf("connected\n");
    return 1;
}
int connect_to_addr(const sockaddr *addr, int addrlen)
{
    local_socket = socket(addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
    if (local_socket == -1)
    {
        printf("unable to create socket\n");
        return -1;
    }

    char str[INET6_ADDRSTRLEN];
    unsigned short port;

    switch (addr->sa_family)
    {
        case AF_INET:
        {
            struct sockaddr_in *saddr = (struct sockaddr_in*)addr;
            inet_ntop(AF_INET, &(saddr->sin6_addr), str, sizeof(str));
            port = ntohs(saddr->sin_port);
            break;
        }

        case AF_INET6:
        {
            struct sockaddr_in6 *saddr = (struct sockaddr_in6*)addr;
            inet_ntop(AF_INET6, &(saddr->sin6_addr), str, sizeof(str));
            port = ntohs(saddr->sin6_port);
            break;
        }
    }

    printf("connecting to address: %s on port: %hu\n", str, port);

    if (connect(local_socket, addr, addrlen) != 0)
    {
        printf("unable to connect\n");

        close(local_socket);
        local_socket = -1;

        return 0;
    }

    printf("connected\n");
    return 1;
}

如何设置TCP套接字服务器以应答该地址

您只需将侦听套接字
bind()
绑定到服务器计算机本地的特定IP地址(使用
getifaddrs()
或等效API获取本地IP列表)。或者使用通配符地址(
INADDR\u ANY
用于IPv4,
in6addr\u ANY
用于IPv6)绑定到所有可用的本地IP


客户端的DNS查找将负责将
设备.local
解析为路由到服务器计算机的IP地址,如果服务器套接字正在该IP上侦听,则它可以
接受()
传入连接。

.local
TLD为MDN保留,如中所述

因此,要使
device.local
正常工作,您的本地系统应设置
device
作为主机名,并应运行Bonjour服务(内置于Windows和OSX,在Linux上作为Avahi提供)

完成后,您的服务器端应用程序根本不需要做任何特殊的事情—它只需将
绑定到
INADDR\u ANY
并在任何接口上接受传入(IPv4)连接

让事情稍微复杂一点的是,如果您也想通过IPv6提供服务,那么通常需要两个侦听套接字,第二个绑定到
in6addr\u any


在客户端,
getaddrinfo()
函数应该能够连接到MDN,并相应地将名称解析为正确的IP地址。

您可以让客户端接受URL(就像web浏览器或telnet客户端一样),但最终,当使用需要它们的套接字API函数时,需要将它们解析为网络地址。你别无选择;底层协议使用地址(即使是虚线地址也不是真实的网络地址,比如URL,它们只是为了方便人类,而不是计算机)。我的客户机接受URL是什么意思?我希望服务器连接到请求地址
device1.local
的客户机。然后服务器成为客户机,同样的原则也适用。所谓客户机,我指的是与服务器建立连接的任何进程。服务器也可以是客户端。无论如何,要使用套接字API通过网络连接,必须将名称解析为网络地址。也许我误解了你的问题。也许你可以看看gethostbyname()函数。也许这就是您要找的。
gethostbyname()
不推荐使用。改用
getaddrinfo()
。我不这么认为。“如果我希望我的客户机将telnet转换为“主机名”而不是数字或十六进制地址,我应该指定哪种格式?”-这就是我的回答,客户机如何将主机名解析为IP,从而连接到该主机。主机名以
.local
结尾这一事实与此无关,DNS系统代表客户端处理此问题。在这种情况下,通过
gethostbyname()
getaddrinfo()
进行内部解析。严格来说,是由系统解析程序决定是使用DNS还是/etc/hosts还是MDN(如果名称与本地配置的mDNS域名匹配,则选择后者,默认为
.local
)。现在回想起来还不是100%清楚,但OP似乎在问(“我如何设置TCP套接字服务器来回答该地址?”)如何使用
inet\u ntop()
选择要绑定的地址,答案是“不要使用
INADDR\u ANY
”,这很有用!“让事情稍微复杂一点的是,如果您也想通过IPv6提供服务,那么您通常需要两个侦听套接字,第二个绑定到
in6addr\u any
”——除非您使用双堆栈套接字,它可以同时为IPv4和IPv6客户端提供服务。
int connect_to_addr(const sockaddr *addr, int addrlen)
{
    local_socket = socket(addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
    if (local_socket == -1)
    {
        printf("unable to create socket\n");
        return -1;
    }

    char str[INET6_ADDRSTRLEN];
    unsigned short port;

    switch (addr->sa_family)
    {
        case AF_INET:
        {
            struct sockaddr_in *saddr = (struct sockaddr_in*)addr;
            inet_ntop(AF_INET, &(saddr->sin6_addr), str, sizeof(str));
            port = ntohs(saddr->sin_port);
            break;
        }

        case AF_INET6:
        {
            struct sockaddr_in6 *saddr = (struct sockaddr_in6*)addr;
            inet_ntop(AF_INET6, &(saddr->sin6_addr), str, sizeof(str));
            port = ntohs(saddr->sin6_port);
            break;
        }
    }

    printf("connecting to address: %s on port: %hu\n", str, port);

    if (connect(local_socket, addr, addrlen) != 0)
    {
        printf("unable to connect\n");

        close(local_socket);
        local_socket = -1;

        return 0;
    }

    printf("connected\n");
    return 1;
}
bool connect_to_host(const char* hostname, unsigned short port)
{
    local_socket = -1;

    printf("resolving %s:%hu\n", hostname, port);

    struct addrinfo hints;
    bzero((void *)&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    char service[6];
    bzero(service, sizeof(service));
    sprintf(service, "%hu", port_number);

    struct addrinfo *addrs = 0;
    if (getaddrinfo(hostname, service, &hints, &addrs) != 0)
    {
        printf("unable to resolve\n");
        return false;
    }

    for(struct addrinfo *addr = addrs; addr != 0; addr = addr->ai_next)
    {
        if (connect_to_addr((struct sockaddr*)(addr->ai_sockaddr), addr->ai_addrlen) != 0)
            break;
    }

    freeaddrinfo(addrs);

    return (local_socket != -1);
}
if (connect_to_host("device.local", 6666))
{
    // use local_socket as needed...
    close(local_socket);
}