- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有这段代码连接到本地 Graphite (实际上只是在本地主机上运行的nc -l -p 2023
):
getCarbonAddr :: Config -> IO SockAddr
getCarbonAddr cfg = do
let host = (graphiteHost . graphiteConfig) cfg
let port = (graphitePort . graphiteConfig) cfg
-- addrInfos <- getAddrInfo (Just defaultHints)
addrInfos <- getAddrInfo Nothing
(Just host)
(Just (show port))
putStrLn $ "addrInfos: " ++ show addrInfos
c <- case addrInfos of
(addrInfo : _) -> return (addrAddress addrInfo)
_ -> unsupportedAddressError host
return c
where
unsupportedAddressError h = ioError $ userError $
"unsupported address: " ++ h
主机和端口的配置值分别为“localhost”和2023。当我升级到 Yosemite 后在 OS X 上运行此程序时,我看到以下崩溃:
addrInfos: [AddrInfo {addrFlags = [], addrFamily = AF_INET6, addrSocketType = Datagram, addrProtocol = 17, addrAddress = [::1]:2023, addrCanonName = Nothing},AddrInfo {addrFlags = [], addrFamily = AF_INET6, addrSocketType = Stream, addrProtocol = 6, addrAddress = [::1]:2023, addrCanonName = Nothing},AddrInfo {addrFlags = [], addrFamily = AF_INET, addrSocketType = Datagram, addrProtocol = 17, addrAddress = 127.0.0.1:2023, addrCanonName = Nothing},AddrInfo {addrFlags = [], addrFamily = AF_INET, addrSocketType = Stream, addrProtocol = 6, addrAddress = 127.0.0.1:2023, addrCanonName = Nothing},AddrInfo {addrFlags = [], addrFamily = AF_INET6, addrSocketType = Datagram, addrProtocol = 17, addrAddress = [fe80::1%lo0]:2023, addrCanonName = Nothing},AddrInfo {addrFlags = [], addrFamily = AF_INET6, addrSocketType = Stream, addrProtocol = 6, addrAddress = [fe80::1%lo0]:2023, addrCanonName = Nothing}]
LocalJob: connect: unsupported operation (Address family not supported by protocol family)
这对我来说很奇怪,所以我决定运行这个 C 程序(在 google 上搜索“getaddrinfo”示例,更改主机名和端口,添加 ai_family 的打印):
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#ifndef NI_MAXHOST
#define NI_MAXHOST 1025
#endif
int main(void)
{
struct addrinfo *result;
struct addrinfo *res;
int error;
/* resolve the domain name into a list of addresses */
error = getaddrinfo("localhost", "2023", NULL, &result);
if (error != 0)
{
fprintf(stderr, "error in getaddrinfo: %s\n", gai_strerror(error));
return EXIT_FAILURE;
}
/* loop over all returned results and do inverse lookup */
for (res = result; res != NULL; res = res->ai_next)
{
char hostname[NI_MAXHOST] = "";
error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, NI_MAXHOST, NULL, 0, 0);
if (error != 0)
{
fprintf(stderr, "error in getnameinfo: %s\n", gai_strerror(error));
continue;
}
if (*hostname != '\0')
printf("hostname: %s. ai_family: %i\n", hostname, res->ai_family);
}
freeaddrinfo(result);
return EXIT_SUCCESS;
}
启动后,我看到了以下输出:
➜ getaddrinfotest ./main
hostname: localhost. ai_family: 30
hostname: localhost. ai_family: 30
hostname: localhost. ai_family: 2
hostname: localhost. ai_family: 2
hostname: localhost. ai_family: 30
hostname: localhost. ai_family: 30
所以,ai_family 30 似乎是一个奇怪的东西。据我了解socket.h sources ,它就是 AF_TIPC 协议(protocol),这是一个我以前没有听说过的非常罕见的东西。我还打开了haskell的packFamily' sources并惊讶地发现它不能处理 30 的值(不知道 AF_TIPC)。
我的问题是:现在最好的做法是什么?我是否正确地理解了问题? Haskell 应该更好地处理未知的人工智能家族吗?//谢谢!
更新:我通过提示使用 ipv4 解决了问题:
addrInfos <- getAddrInfo (Just (defaultHints { addrFamily=AF_INET }))
(Just host)
(Just (show port))
但我仍然想知道如何“以正确的方式”解决这个问题。
最佳答案
默认情况下,getaddrinfo
(及其 Haskell 绑定(bind) getAddrInfo
)返回 addrinfo 的链接列表,其中可以包含 IPv4 地址、IPv6 地址或两者的混合。不幸的是,sockets 函数不允许将 IPv4 套接字连接到 IPv6 地址,因此当您迭代地址列表时,您需要创建正确类型的套接字:
addrinfos <- getAddrInfo Nothing (Just hostname) (Just (show port))
let first = head addrinfos
sock <- socket (addrFamily first) Stream defaultProtocol
connect sock (addrAddress first)
请注意如何将(首先是addrFamily)
传递给socket
函数,以便在正确的协议(protocol)族中创建套接字。
在实际代码中,您需要迭代列表 addrinfos
并尝试连接到 getAddrInfo
返回的所有地址。当您这样做时,不要忘记关闭连接失败的套接字。
关于c - Haskell:不支持的操作(协议(protocol)族不支持地址族),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26588469/
在C中,protocol family被提及为第一个参数。 例如: ipv4 的套接字(AF_INET,,) socket(AF_PACKET,,) 用于数据包嗅探 Python 支持三个地址族:AF
根据 vfork() 手册页,如果 vfork() 在调用 _exit 或 exec 之前修改除 pid_t 之外的任何数据,则行为未定义系统调用系列。 由此我了解到,如果vfork()创建的子进程调
我是一名优秀的程序员,十分优秀!