WinSock连接前绑定导致WSAEADDRNOTAVAIL-请求的地址在其上下文中无效
WinSock bind before connects results in WSAEADDRNOTAVAIL - The requested address is not valid in its context
我需要使用WinSock从特定的本地网卡打开一个套接字。我问过这个问题,在这里得到了答案。简而言之,答案建议您首先绑定到本地接口,然后调用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);
EDIT:此示例代码有意不进行错误检查,以便以最有效的方式传达我的意图。
编辑2:绑定到192.168.1.3会导致连接失败。绑定127.0.0.1有效。是的,我100%确信192.168.1.3是正确的本地IP。
编辑3:对!一时兴起,我在家用电脑上试用了这个测试应用程序,效果很好。所以,至少代码确实有效,而且问题一定与我的工作电脑有关。
好吧,事实证明@captrap是对的。
我已经禁用了我的防火墙,但我不知道,我们的IT部门有一些其他的防火墙功能紧密集成到企业病毒扫描仪中(我无法卸载或禁用)。一旦我设法让IT暂时禁用它,一切都如预期的那样工作。
调用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...
}
代码实际有多远?
相关文章:
- 将数组的地址分配给变量并删除
- 空基优化子对象的地址
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- #为""定义宏;静态";针对不同的上下文
- 与互斥锁相比,旋转锁可以保证上下文切换
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 如何在c++程序中找到函数的地址
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 被解释为低级别const的const对象的地址
- 为什么我不能使用 EGL 创建无头 OpenGl 上下文?
- 将地址分配给本地指针后,公共对象的变量将消失
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 内联程序集printf将整数解释为地址
- 为什么指针不写入类的地址?
- 如何在C++中获取该对象的类声明中对象的地址?
- 通过按地址访问变量
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 如何在没有网络表条目上下文时删除 IP 地址