在 Windows 中为套接字使用特定的网络接口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2065495/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 07:03:35  来源:igfitidea点击:

Using a specific network interface for a socket in windows

windowsnetworkingbindingsocketsbind

提问by Ofir

Is there a reliable way in Windows, apart from changing the routing table, to force a newly created socket to use a specific network interface? I understand that bind()to the interface's IP address does not guarantee this.

除了更改路由表外,Windows 中是否有可靠的方法来强制新创建的套接字使用特定的网络接口?我了解bind()接口的 IP 地址并不能保证这一点。

采纳答案by Ezz

(Ok second time lucky..)

(好吧,第二次幸运..)

FYI there's another question here perform connect() on specific network adapteralong the same lines...

仅供参考,这里还有一个问题,请按照相同的方式在特定网络适配器上执行 connect()...

According to The Cable Guy

根据接线员的说法

Windows XP and Windows Server? 2003 use the weak host model for sends and receives for all IPv4 interfaces and the strong host model for sends and receives for all IPv6 interfaces. You cannot configure this behavior. The Next Generation TCP/IP stack in Windows Vista and Windows Server 2008 supports strong host sends and receives for both IPv4 and IPv6 by default on all interfaces except the Teredo tunneling interface for a Teredo host-specific relay.

Windows XP 和 Windows Server?2003 对所有 IPv4 接口的发送和接收使用弱主机模型,对所有 IPv6 接口的发送和接收使用强主机模型。您无法配置此行为。默认情况下,Windows Vista 和 Windows Server 2008 中的下一代 TCP/IP 堆栈在除 Teredo 主机特定中继的 Teredo 隧道接口之外的所有接口上都支持 IPv4 和 IPv6 的强主机发送和接收。

So to answer your question (properly, this time) in Windows XP and Windows Server 2003 IP4 no, but for IP6 yes. And for Windows Vista and Windows 2008 yes (except for certain circumstances).

因此,要在 Windows XP 和 Windows Server 2003 IP4 中回答您的问题(这次正确),IP4 否,但 IP6 是。而对于 Windows Vista 和 Windows 2008 是的(某些情况除外)。

Also from http://www.codeguru.com/forum/showthread.php?t=487139

同样来自http://www.codeguru.com/forum/showthread.php?t=487139

On Windows, a call to bind() affects card selection only incoming traffic, not outgoing traffic. Thus, on a client running in a multi-homed system (i.e., more than one interface card), it's the network stack that selects the card to use, and it makes its selection based solely on the destination IP, which in turn is based on the routing table. A call to bind() will not affect the choice of the card in any way.

It's got something to do with something called a "Weak End System" ("Weak E/S") model. Vista changed to a strong E/S model, so the issue might not arise under Vista. But all prior versions of Windows used the weak E/S model.

With a weak E/S model, it's the routing table that decides which card is used for outgoing traffic in a multihomed system.

See if these threads offer some insight:

"Local socket binding on multihomed host in Windows XP does not work" at http://www.codeguru.com/forum/showthread.php?t=452337

"How to connect a port to a specified Networkcard?" at http://www.codeguru.com/forum/showthread.php?t=451117. This thread mentions the CreateIpForwardEntry() function, which (I think) can be used to create an entry in the routing table so that all outgoing IP traffic with a specified server is routed via a specified adapter.

"Working with 2 Ethernet cards" at http://www.codeguru.com/forum/showthread.php?t=448863

"Strange bind behavior on multihomed system" at http://www.codeguru.com/forum/showthread.php?t=452368

在 Windows 上,对 bind() 的调用仅影响传入流量,而不影响传出流量。因此,在多宿主系统中运行的客户端(即,多个接口卡)上,选择要使用的卡的是网络堆栈,它仅根据目标 IP 进行选择,而目标 IP 又是基于在路由表上。调用 bind() 不会以任何方式影响卡片的选择。

它与所谓的“弱端系统”(“Weak E/S”)模型有关。Vista 更改为强 E/S 模型,因此在 Vista 下可能不会出现此问题。但是所有以前版本的 Windows 都使用弱 E/S 模型。

对于弱 E/S 模型,路由表决定了在多宿主系统中将哪张卡用于传出流量。

看看这些线程是否提供了一些见解:

“Windows XP 中多宿主主机上的本地套接字绑定不起作用”,网址http://www.codeguru.com/forum/showthread.php?t=452337

“如何将端口连接到指定的网卡?” 在 http://www.codeguru.com/forum/showthread.php?t=451117。这个线程提到了 CreateIpForwardEntry() 函数,它(我认为)可用于在路由表中创建一个条目,以便通过指定的适配器路由与指定服务器的所有传出 IP 流量。

“使用 2 个以太网卡”在 http://www.codeguru.com/forum/showthread.php?t=448863

http://www.codeguru.com/forum/showthread.php?t=452368上的“多宿主系统上的奇怪绑定行为”

Hope that helps!

希望有帮助!