我需要使用WinSock从特定的本地网卡打开套接字。我问过这个并得到答案here。简而言之,答案建议您首先绑定到本地接口,然后调用connect。
然而,当我这样做时,我得到一个WSAEADDRNOTAVAIL(10049)“请求的地址在其上下文中无效。”为什么是这样?
假设下面的示例代码是在本地机箱192.168.1.3上运行的应用程序的一部分,并且正在尝试连接到远程服务器192.168.1.4。我检查并仔细检查了本地和远程地址是否正确。我可以双向ping(从本地到远程,从远程到本地)。
我为本地尝试过0以外的端口;没有不同。如果我在连接之前删除了绑定,那么它可以工作,但我无法指定网络接口。
那么,任何想法为什么我一直得到WSAEADDRNOTAVAIL?
addrinfo localhints = {0};
localhints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
localhints.ai_family = AF_INET;
localhints.ai_socktype = SOCK_STREAM;
localhints.ai_protocol = IPPROTO_TCP;
addrinfo *localaddr = NULL;
getaddrinfo("192.168.1.3", "0", &localhints, &localaddr);
bind(s, localaddr->ai_addr, localaddr->ai_addrlen);
freeaddrinfo(localaddr);
addrinfo remotehints = {0};
remotehints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
remotehints.ai_family = AF_INET;
remotehints.ai_socktype = SOCK_STREAM;
remotehints.ai_protocol = IPPROTO_TCP;
addrinfo *remoteaddr = NULL;
getaddrinfo("192.168.1.4", "12345", &remotehints, &remoteaddr);
connect(s, remoteaddr->ai_addr, remoteaddr->ai_addrlen);
freeaddrinfo(remoteaddr);
编辑:此示例代码故意没有错误检查,因此我的意图可以以最有效的方式传达。
编辑2 :绑定到192.168.1.3会导致连接失败。绑定到127.0.0.1工作。是的,我100%确定192.168.1.3是正确的本地IP。
编辑3 :对!一时兴起,我在家用电脑上试用了测试应用程序,它运行正常。所以,至少代码确实有效,麻烦必须与我的工作PC有关。
答案 0 :(得分:1)
好的,结果证明@claptrap是对的。
我已经禁用了防火墙,但我不知道,我们的IT部门还有其他一些与企业病毒扫描程序紧密集成的防火墙(我无法卸载或禁用)。一旦我设法让IT暂时禁用它,一切都按预期工作。
答案 1 :(得分:0)
调用API函数时始终检查错误代码,例如:
addrinfo localhints = {0};
localhints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
localhints.ai_family = AF_INET;
localhints.ai_socktype = SOCK_STREAM;
localhints.ai_protocol = IPPROTO_TCP;
addrinfo *localaddr = NULL;
int ret = getaddrinfo("192.168.1.3", "0", &localhints, &localaddr);
if (ret == 0)
{
ret = bind(s, localaddr->ai_addr, localaddr->ai_addrlen);
freeaddrinfo(localaddr);
if (ret == 0)
{
addrinfo remotehints = {0};
remotehints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
remotehints.ai_family = AF_INET;
remotehints.ai_socktype = SOCK_STREAM;
remotehints.ai_protocol = IPPROTO_TCP;
addrinfo *remoteaddr = NULL;
ret = getaddrinfo("192.168.1.4", "12345", &remotehints, &remoteaddr);
if (ret == 0)
{
ret = connect(s, remoteaddr->ai_addr, remoteaddr->ai_addrlen);
freeaddrinfo(remoteaddr);
if (ret == 0)
{
// connect succeeded...
// can use getsockname() here to discover which port was actually bound to, if needed.
// On some OS versions, bind() does not perform the actual binding immediately,
// connect() does the actual binding instead since it can make more informed choices based on the target address being connected to...
}
else
{
// connect failed...
}
}
else
{
// getaddrinfo() failed
}
}
else
{
// bind failed
}
}
else
{
// getaddrinfo() failed...
}
代码到底有多远?