- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
getaddrinfo接受 struct addrinfo *hints
作为第三个参数,可用于指定选择要由该函数返回的套接字地址的标准。
文档说我们可以设置 ai_socktype
以及 ai_protocol
来指定我们的选择标准。但是,如果我们已经指定了 ai_socktype
,我无法理解为什么需要 ai_protocol
。如果指定了这两者之一,那么另一个似乎是多余的。
这是我编写的一些代码来对此进行试验。
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
void getaddrinfo_demo(const char *node, const char *service,
int socktype, int protocol)
{
struct addrinfo hints, *res, *p;
int error;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = socktype;
hints.ai_protocol = protocol;
error = getaddrinfo(node, service, &hints, &res);
if (error) {
printf("Error %d: %s\n\n", error, gai_strerror(error));
return;
}
for (p = res; p != NULL; p = p->ai_next) {
struct sockaddr_in *addr = ((struct sockaddr_in *) p->ai_addr);
char ip[INET_ADDRSTRLEN];
int port = ntohs(addr->sin_port);
inet_ntop(AF_INET, &addr->sin_addr, ip, INET_ADDRSTRLEN);
printf("ip: %s; port: %d; protocol: %d\n", ip, port, p->ai_protocol);
}
printf("\n");
freeaddrinfo(res);
}
int main()
{
/* Consistent family and socktype works fine. */
getaddrinfo_demo("localhost", "http", SOCK_STREAM, IPPROTO_TCP);
getaddrinfo_demo("localhost", "http", SOCK_DGRAM, IPPROTO_UDP);
/* Inconsistent family and sock type leads to error -7. */
getaddrinfo_demo("localhost", "http", SOCK_STREAM, IPPROTO_UDP);
getaddrinfo_demo("localhost", "http", SOCK_DGRAM, IPPROTO_TCP);
}
这是输出。
$ gcc -std=c99 -D_POSIX_SOURCE -Wall -Wextra -pedantic foo.c && ./a.out
ip: 127.0.0.1; port: 80; protocol: 6
ip: 127.0.0.1; port: 80; protocol: 6
ip: 127.0.0.1; port: 80; protocol: 17
ip: 127.0.0.1; port: 80; protocol: 17
Error -7: ai_socktype not supported
Error -7: ai_socktype not supported
如您所见,如果 ai_socktype = AF_STREAM
,则只有 ai_protocol = IPPROTO_TCP
有效。指定 ai_protocol = IPPROTO_UDP
会导致错误。如果我们不能通过它指定任何额外的选择标准,那么也可以省略在 hints
中指定 ai_protocol
。
那么 ai_protocol
在 hints
中的真正作用是什么?您能否举例说明 ai_socktype
和 ai_protocol
都具有某种用途?
最佳答案
这些怎么样:
getaddrinfo_demo("localhost", "http", SOCK_STREAM, IPPROTO_SCTP);
getaddrinfo_demo("localhost", "imap", SOCK_STREAM, IPPROTO_TCP);
getaddrinfo_demo("localhost", "imap", SOCK_STREAM, IPPROTO_SCTP);
getaddrinfo_demo("localhost", "sbcap", SOCK_STREAM, IPPROTO_SCTP);
getaddrinfo_demo("localhost", "sbcap", SOCK_SEQPACKET, IPPROTO_SCTP);
getaddrinfo_demo("localhost", "sbcap", SOCK_STREAM, IPPROTO_TCP);
getaddrinfo_demo("localhost", "http", SOCK_DGRAM, IPPROTO_UDPLITE);
getaddrinfo_demo("localhost", "syslog-tls", SOCK_DCCP, IPPROTO_DCCP);
哪个给你:
ip: 127.0.0.1; port: 80; protocol: 132
ip: 127.0.0.1; port: 143; protocol: 6
Error -8: Servname not supported for ai_socktype
ip: 127.0.0.1; port: 29168; protocol: 132
ip: 127.0.0.1; port: 29168; protocol: 132
Error -8: Servname not supported for ai_socktype
Error -8: Servname not supported for ai_socktype
ip: 127.0.0.1; port: 6514; protocol: 33
所以 TCP 不是唯一的流协议(protocol),UDP 也不是唯一的数据报协议(protocol)(尽管 DCCP 有自己的 SOCK_DCCP
并且 UDP-Lite 在服务数据库中没有任何条目(有人可能会争辩说它不需要,因为 UDP-Lite RFC 明确表示“UDP-Lite 使用由 IANA 分配给 UDP 使用的同一组端口号值”)。
现在我们在实践中并不经常看到它,但是如果我们谈论像 getaddrinfo()
这样的 API,它们必须被设计成面向 future 的,这包括做一些看似多余的事情。只有时间才能证明这些东西是否真的是多余的。在这种情况下不是,恰恰相反。如果FreeBSD man page是正确的,那么
The implementation first appeared in WIDE Hydrangea IPv6 protocol stack kit.
仍然存在 FAQ关于互联网上的这个协议(protocol)栈,从中我们可以猜测它是在1997--1998年左右创建的(我还没有那么大的内存力,我也没有看到任何其他合适的来源,所以请纠正我'我错了)。和 SCTP was defined 2000 年。正如我在上面的示例中所展示的,我们使用此 API 的 SCTP 没有任何问题。 2005--2006 年左右出现的与 DCCP 相同的故事,非常适合相同的 API。
关于c - 当已经指定了 ai_socktype 时调用 getaddrinfo() 时 ai_protocol 可以在提示中起到什么额外的作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39474941/
我以前有过这个工作,但我不明白如何工作,所以我尝试重写一些代码。 一切似乎都很顺利,除了当我尝试使用 getaddrinfo() 时,我得到的结果是 -7,这意味着错误“ai_socktype 不支持
struct addrinfo *myAddrinfo, *curMyAddrinfo, hint; memset(&hint, 0, sizeof(struct addrinfo)); hint.a
我正在使用 Vagrant 运行 Centos 虚拟机。机器似乎运行正常,但是当我尝试同步 Perforce 时,我可以看到以下错误: [vagrant@vagrant-c5-x86_64 ~]$ /
我无法通过 paramiko 连接到其他服务器: import paramiko import sys import os hostname = 'server1' port = 22 usernam
我正在尝试实现一个 IPv6 UDP 客户端-服务器应用程序,它将让我获得逐跳扩展 header 的详细信息。因此,为此我想我必须使用 SOCK_RAW 来访问 IPv6 header 信息。 现在在
所以,在我得到这个错误之后,我一直在这里寻找答案,几乎每个人都有一个很难解决这个错误的方法,但是没有人解释为什么会发生这个错误,所以我不认为这个问题是完全重复。 我用 C 语言编写了一个 TCP 套接
我正在尝试用 C 编写套接字程序。当我这样做时,我的整个代码都可以正常工作 #define PORT "3333" 但不是 #define PORT getParameter("setting.ini
我观察到,这是因为端口。端口是 C++ 字符串。当我硬编码端口号时说“4091”我没有看到这个问题。有什么建议吗? int sockfd; struct addrinfo hints, *servin
假设以下代码模拟了 resolveip 实用程序的基本功能: #define _POSIX_SOURCE /* getaddrinfo() */ #include /* getaddr
getaddrinfo接受 struct addrinfo *hints 作为第三个参数,可用于指定选择要由该函数返回的套接字地址的标准。 文档说我们可以设置 ai_socktype 以及 ai_pr
我从 git 收到这条错误消息。这是什么意思?如何修复? 最佳答案 我认为这与 Git 无关,而是与运行 Git 的服务器有关。 参见 this article what could this mea
我是一名优秀的程序员,十分优秀!