为应用程序select许多Internet连接之一
我有一台电脑有几个不同的互联网连接。 局域网,无线局域网,WiFi或3G。 所有这些都是活动的,机器可以使用其中的任何一个。
现在我想告诉我的应用程序使用其中一个可用的连接。 例如,我想告诉我的应用程序只使用WiFi,而其他软件可能使用其他的东西。
在我的C#应用程序中,我使用类如HttpWebRequest
和HttpWebResponse
。
这甚至有可能吗?
这是由HttpWebRequest,WebRequest,WebClient等提供的高级function。 但是,您可以使用TcpClient
(使用构造函数获取本地端点 )或使用套接字并调用Socket.Bind来完成此操作 。
如果您需要使用特定的本地端点,请使用“绑定”方法。 您必须先调用绑定,然后才能调用Listen方法。 除非需要使用特定的本地端点,否则在使用Connect方法之前,不需要调用Bind。
绑定到您要使用的接口的本地端点。 如果您的本地计算机的IP地址为192.168.0.10,那么使用本地端点将强制套接字使用该接口。 默认值是未绑定的(真的是0.0.0.0),它告诉networking堆栈自动parsing接口,这是你想避开的。
以下是一些基于Andrew评论的示例代码。 请注意,将0指定为本地端点端口意味着它是dynamic的。
using System.Net; using System.Net.Sockets; public static class ConsoleApp { public static void Main() { { // 192.168.20.54 is my local network with internet accessibility var localEndPoint = new IPEndPoint(IPAddress.Parse("192.168.20.54"), port: 0); var tcpClient = new TcpClient(localEndPoint); // No exception thrown. tcpClient.Connect("stackoverflow.com", 80); } { // 192.168.2.49 is my vpn, having no default gateway and unable to forward // packages to anything that is outside of 192.168.2.x var localEndPoint = new IPEndPoint(IPAddress.Parse("192.168.2.49"), port: 0); var tcpClient = new TcpClient(localEndPoint); // SocketException: A socket operation was attempted to an unreachable network 64.34.119.12:80 tcpClient.Connect("stackoverflow.com", 80); } } }
在ServicePoint.BindIPEndPointDelegate上查看此MSDN 博客条目 。 它解释了如何显式创build将由HttpWebRequest使用的本地端点。
例如,绑定到192.168.16.100:
WebRequest webReq = WebRequest.Create(myUri); HttpWebRequest httpRequest = (HttpWebRequest)webReq; httpRequest.ServicePoint.BindIPEndPointDelegate = new BindIPEndPoint(BindIPEndPointCallback); ... private static IPEndPoint BindIPEndPointCallback(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount) { if (remoteEndPoint.AddressFamily == AddressFamily.InterNetwork) { return new IPEndPoint(IPAddress.Parse("192.168.16.100"), 0); } // Just use the default endpoint. return null; }
你绝对可以做到这一点:
Uri uri = new Uri(url, UriKind.Absolute); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); ServicePoint servicePoint = ServicePointManager.FindServicePoint(uri); servicePoint.BindIPEndPointDelegate = new BindIPEndPoint(Bind); //execute the request response = (HttpWebResponse)request.GetResponse(); Stream receiveStream = response.GetResponseStream();
你可能需要这个:
private IPEndPoint Bind(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount) { IPAddress address = IPAddress.Parse(GetHostIP()); return new IPEndPoint(address, 0); }
获取特定适配器的IP:
private string GetIPfromNetworkCard(string EthernetCardName) { string Ret = ""; foreach (NetworkInterface netif in NetworkInterface.GetAllNetworkInterfaces()) { if (netif.Name == EthernetCardName) { IPInterfaceProperties properties = netif.GetIPProperties(); //foreach (IPAddressInformation unicast in properties.UnicastAddresses) //{ // Select the first one... Ret = properties.UnicastAddresses[0].Address.ToString(); break; //} } } return Ret; }
不,它不可能使用任何C#类 – 它们都在太高的级别上运行,以至于在TCP / IP级别(甚至套接字太高)。 Windows TCP / IP堆栈使用路由表和接口指标来确定将数据包发送出去的接口。
您可以通过调用GetBestInterfaceEx()来查看Windows TCP / IP堆栈确定哪个接口具有最佳路由(它将用于发送数据包的接口) 。
在前雇主中,我们试图做一些类似的事情,把stream量分离到不同的网卡上,把一个套接字绑定到我们想要发送stream量的网卡的IP地址上。 然而,Windows会将stream量发送出去,看到它具有最佳路由的NIC(具有与源不同的IP地址的NIC)。 在我们弄清楚发生了什么之前,我们花了一些脑筋。
因此,使用原始套接字或libpcap(可能是嘲笑,你将不得不build立自己的TCP / IP和HTTP处理程序)做一些事情(或许),但是你不能在Windows上这样做。