- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
int print_socket_info(int sock_fd, struct sockaddr_in *sin, short protocol){
char dbg[INET_ADDRSTRLEN];
char *famstr;
inet_ntop(protocol, &(sin->sin_addr), dbg, INET_ADDRSTRLEN);
printf("============ SOCKET INFORMATION =============\n");
printf("!** socket: %d\n", sock_fd);
printf("!** info->ai_addr: sockaddr_in(\n");
famstr = fam2str(sin->sin_family);
printf("!** sin_family: %s\n", famstr);
printf("!** sin_port: %d\n", ntohs(sin->sin_port));
printf("!** sin_addr: in_addr( s_addr : '%s' )\n", dbg);
printf("!**)\n");
printf("=============================================\n");
return 1;
}
char *fam2str(int fam){
switch (fam){
case AF_INET:
return "AF_INET";
case AF_INET6:
return "AF_INET6";
case AF_UNSPEC:
return "AF_UNSPEC";
default:
return "(UNKNOWN)";
}
return "(UNKNOWN)";
}
如果我传入hint.ai_addr(忽略信息->...那是字符串的一部分),如下所示:
print_socket_info(sock, (struct sockaddr_in *)hint.ai_addr, protocol);
...然后我打印出以下内容...
============ SOCKET INFORMATION =============
!** socket: 3
!** info->ai_addr: sockaddr_in(
!** sin_family: AF_INET6
!** sin_port: 8081
!** sin_addr: in_addr( s_addr : '::1' )
!**)
=============================================
...信息打印正确。接下来我调用该函数:
res = getaddrinfo(target_host, target_port, &hint, &info);
到目前为止我没有收到任何错误。现在,我循环遍历链表:
struct addrinfo *rp;
for (rp = info; rp != NULL; rp = rp->ai_next){
printf("==> Another element.\n");
print_socket_info(sock, (struct sockaddr_in *) rp->ai_addr, protocol);
}
...我只打印出一个元素:
============ SOCKET INFORMATION =============
!** socket: 3
!** info->ai_addr: sockaddr_in(
!** sin_family: AF_INET6
!** sin_port: 8081
!** sin_addr: in_addr( s_addr : '::' )
!**)
=============================================
...当然,这对bind()造成了严重破坏。为什么地址被缩短了?
还有一点很奇怪:如果我传入 127.0.0.1 并使用 AF_INET4,那么该地址将在整个程序中保留(尽管我只得到一个结果,但绑定(bind)仍然失败)。
有什么想法吗?提前致谢。
最佳答案
您的print_socket_info
函数是错误的。如果采用 struct sockaddr_in *(IPv4 套接字地址结构),但它意味着同时支持 IPv4 和 IPv6。
您必须声明print socket_info
以获取通用struct sockaddr *
(任何类型的套接字地址)。为了更好的措施:将 sin
参数重命名为 sa
以表明它是泛型类型,而不是 struct sockaddr_in
类型。然后,在函数内部,检查 sin->sin_family
以找出实际的系列,并继续将 sin
转换为 struct sockaddr_in *
或 struct sockaddr_in6
(视情况而定)。
现有函数中发生的情况是,您只是在整个函数中将其视为 struct sockaddr_in *
,结果如下(至少在 Linux 上):
sin_family
是可以的,因为可以保证该系列在所有类型的 sockaddrs 的结构中具有相同的偏移量,无论是 struct sockaddr_in
还是 struct sockaddr_in6
甚至用于 UNIX 域套接字的 struct sockaddr_un
或用于所有其他晦涩地址系列的 sockaddr 结构。sin_port
时逃脱了它,因为 struct sockaddr_in
中的 sin_port
恰好位于结构中的相同偏移处作为struct sockaddr_in6
中的sin6_port
。sin_addr
不起作用,因为对于 IPv4,sin_addr
紧接在结构中的 sin_port
之后,但对于 IPv6,其他一些字段可在该位置找到(即 sin6_flowinfo
)。 sin6_addr
在其他地方。print_socket_info
的另一个问题是您的字符串缓冲区只有足够的空间容纳 IPv4 地址字符串,因为它声明的长度 INET_ADDRSTRLEN
对于 IPv6 来说太短了(对于 IPv6,您需要 INET6_ADDRSTRLEN
。并且该函数不需要采用参数 protocol
。此信息已嵌入到 sockaddr 中。
int print_socket_info(int sock_fd, struct sockaddr *sa){
char dbg[INET6_ADDRSTRLEN]; /* the larger of the two sizes */
char *famstr;
unsigned short port;
switch (sa->sa_family):
case AF_INET4:
inet_ntop(AF_INET4, &(((struct sockaddr_in *)sa)->sin_addr), dbg, sizeof(dbg));
port = ((struct sockaddr_in *)sa)->sin_port;
break;
case AF_INET6:
inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr), dbg, sizeof(dbg));
port = ((struct sockaddr_in6 *)sa)->sin6_port;
break;
default:
strcpy(dst, "UNKNOWN");
port = 0;
}
printf("============ SOCKET INFORMATION =============\n");
printf("!** socket: %d\n", sock_fd);
printf("!** info->ai_addr: sockaddr_in(\n");
famstr = fam2str(sa->sa_family);
printf("!** sa_family: %s\n", famstr);
printf("!** sin[6]_port: %d\n", ntohs(port));
printf("!** sin[6]_addr: in_addr( s_addr : '%s' )\n", dbg);
printf("!**)\n");
printf("=============================================\n");
return 1;
}
关于c - getaddrinfo 删除最后一个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14532785/
我目前正在升级我们的软件以支持 ipv6,同时我正在将主机名/ip 字段扩展到最大主机名大小。在 sun 文档中,它似乎可以达到 1025(netdb.h:#define NI_MAXHOST 102
我正在使用 docker-compose 为开发人员提供技术栈 ROR、postgres、redis、mongo 的开发环境。 docker-compose build 运行成功,但是当我运行 doc
nc -zv cms-01 5061 失败: nc: getaddrinfo: 没有与主机名关联的地址 但是 ping/dig 工作正常。用getent可以看到最不一样的地方: # getent ho
我正在测试一条错误路径,该路径要求我删除来自 getaddrinfo 的请求。我设置了 2 个虚拟机: RHEL 7.9 Ubuntu 20 代码在两台机器上是相同的,只是为 test.com 调用
当我调用 getaddrinfo与 AF_UNSPEC ,理论上它可以返回任何它喜欢的地址族:AF_INET , AF_INET6 ,也许是 AppleTalk、蓝牙、datalink、netlink
我花了几个小时试图找出我的问题,只是在我写问题的时候找到了解决方案(当你需要正式化你的问题并解释它时,它总是有帮助的)。我发布它,希望它可以帮助某人。 使用 getaddrinfo,如果我尝试将套接字
我尝试通过给 getaddrinfo 赋予 http(s) 前缀来使用它,但它无法正确查找主机。我该如何解决这个问题。我要查 https://www.google.com但 gai_strerror(
我想在我的 header 中定义一个端口号(例如 #define port 9191 )并使用它来调用 getaddrinfo() 。但我收到错误,因为参数服务是 char const* 。如何使用#
我对 getaddrinfo() 的行为有疑问,这似乎取决于服务参数的指定方式。将服务指定为名称会导致 getaddrinfo() 使用 getservbyname() 来查询/etc/service
我有一个程序(用 C 语言编写),它使用 getaddrinfo() ,它的第一个参数是我希望它获取地址信息的主机名,假设它是“域”。在同一台计算机上的 /etc/hosts 文件中,我可以看到“do
int print_socket_info(int sock_fd, struct sockaddr_in *sin, short protocol){ char dbg[INET_ADDRS
这个问题已经存在: Login and Registration in Android with PHP, MySQL and SQLite 已关闭 7 年前。 我正在尝试连接到我的 mysql wa
我想连接sql数据库。我究竟做错了什么?请帮忙 常量.php 连接.php 最佳答案 首先,您的 constants.php 文件似乎在开始的 PHP 标记中有错字。您应该按如下方式更新文件:
我目前正在尝试编写自己的 HTTP 代理。我的代码可以正常工作,但我尝试使用 ApacheBench 对其进行压力测试,发现时不时地收到如下消息: “getaddrinfo:提供了节点名或服务名,或者
我正在使用 getaddrinfo() API 来解析跨平台 C++ 应用程序中的 DNS 查询。我需要知道 getaddrinfo() 在不同平台上的时间成本?谁能帮我解决这个问题? 最佳答案 这个
我有一个使用套接字的程序。在客户端,我通过 getaddrinfo 获取必要的信息,然后将结果传递给连接函数。事情是,它在不同的环境中工作不同。在获取 addrinfo 结构并将其传递给 connec
我有一个网络地址,例如 - 192.168.74.0/24。尝试使用 getaddrinfo 获取网络地址转换似乎不起作用。这里的名称是 192.168.74.0/24。 getaddrindo 的返
所以我花了一段时间才弄明白,因为“段错误”没有显示任何代码行,但显然这会导致我的程序出现段错误: if (getaddrinfo(options.servername, (char *)options
我遇到了一个奇怪的问题。我有这个 Python 应用程序,当我尝试在应用程序中打开 url 时,例如 urllib2.urlopen("http://google.com", None) 我收到以下错
我在 LAN 中用于某些套接字通信应用程序的目标机器具有用于 IPv4 的 192.168.98.91。 当我尝试使用 getaddrinfo() 解析 IP 地址时,它返回 127.0.0.1 如何
我是一名优秀的程序员,十分优秀!