套接字如何知道要使用哪个网络接口控制器?

时间:2010-11-28 14:56:11

标签: sockets networking

如果一台计算机有多个网卡,所有网卡都连接到不同的网络并正常运行,当我们打开一个套接字时,操作系统如何确定哪个网卡用于此套接字?套接字API是否允许我们显式指定要使用的NIC?

4 个答案:

答案 0 :(得分:50)

我是从Linux的角度编写的,但我认为它适用于所有地方。

在绑定套接字时做出决定。调用bind时,您指定的地址决定了套接字将侦听的接口。 (甚至是所有接口。)

即使您不使用bind,也会在您connect时隐式发生。在路由表中查找目标,该路由表必须包含到目标网络的路由。该路由还包含要使用的接口,甚至可以指定源地址。如果未指定源地址,则采用接口的主地址。

您实际上可以将bindconnect一起使用,以强制您的传出连接使用特定的地址和端口。套接字必须始终具有这两位信息,因此即使不这样做,也会使用主地址并选择随机端口。

答案 1 :(得分:29)

(如果你觉得倾向于投票,@Shtééf的答案应该比我的更多。)

这取决于您是连接还是绑定。

如果你绑定,你可以绑定到一个机器接口对应的特定IP地址,或者你可以绑定到0.0.0.0,在这种情况下套接字将监听所有接口。

如果连接未绑定的套接字,则机器的路由表与目标IP地址一起将确定连接请求所在的接口。

可以绑定套接字然后连接它。在这种情况下,套接字在进行连接时将根据绑定调用保持绑定。 (感谢@RemyLebeau指出这一点。)

答案 2 :(得分:0)

我不确定哪种方法最好,但是对于shtééf提出的bind() - before-connect()方法有另一种理论。它是使用带有SO_BINDTODEVICE的setsockopt()。请参阅:http://codingrelic.geekhold.com/2009/10/code-snippet-sobindtodevice.html

答案 3 :(得分:0)

作为替代,您可以根据名称搜索适当的nic:

        //Find the ip address based on the ethernet adapter name. On my machine the ethernet adapter is "Ethernet"
        System.Net.NetworkInformation.NetworkInterface[] nics = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
        System.Net.NetworkInformation.NetworkInterface ethernet = nics.Where(n => n.Name.Equals("Ethernet")).Single();
        UnicastIPAddressInformation uniCastIPAddressInformation = ethernet.GetIPProperties().UnicastAddresses.Where(a => a.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).Single();

        IPEndPoint localEndPoint = new IPEndPoint(uniCastIPAddressInformation.Address, 9000);

        //Create a TCP/IP socket.  
        Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //Bind and start listening
        listener.Bind(localEndPoint);
        listener.Listen(10);