4

自家製の発見ツールを使って、興味のあるサービスのリストを発見しました。

私は彼らのIP、サービス名、ポート、ホストなどを持っています...しかし、それらを使用するには、使用するIPをクライアントライブラリに指定する必要があります。

私はいくつかのネットワークカードを持っているので、私が知っている宛先IPとの通信にどのインターフェイスが使用されているかを検出し、それをIPAddressライブラリに渡す必要があります。

しかし、どのインターフェイスIPを使用する必要があるかをどのように検出できますか?

インターネットで検索してみましたが、関連性のあるものが見つからないため、適切なキーワードがないと思います。

4

3 に答える 3

10

関連するメソッドを、私が開発したネットワーク ライブラリnetworkComms.netから引き出しました。

/// <summary>
/// Determines the most appropriate local end point to contact the provided remote end point. 
/// Testing shows this method takes on average 1.6ms to return.
/// </summary>
/// <param name="remoteIPEndPoint">The remote end point</param>
/// <returns>The selected local end point</returns>
public static IPEndPoint BestLocalEndPoint(IPEndPoint remoteIPEndPoint)
{    
    Socket testSocket = new Socket(remoteIPEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
    testSocket.Connect(remoteIPEndPoint);
    return (IPEndPoint)testSocket.LocalEndPoint;
}

正しい IP を取得したら、反復しNetworkInterface.GetAllNetworkInterfaces()て一致するアダプターを見つけることができます。

于 2013-02-26T10:50:29.777 に答える
1

以下は、ルーティング テーブルを照会することによって機能します。Socket.Connectこれは、使用するローカル エンドポイントを決定するのと同じ方法です。違い:

  • ファイアウォールが原因で失敗することはありません
  • リモート エンドポイントが存在しないために失敗することはありません
  • ローカルポートを予約しません
  • もっと早く

.

private static IPEndPoint QueryRoutingInterface(
          Socket socket,
          IPEndPoint remoteEndPoint)
{
    SocketAddress address = remoteEndPoint.Serialize();

    byte[] remoteAddrBytes = new byte[address.Size];
    for (int i = 0; i < address.Size; i++) {
        remoteAddrBytes[i] = address[i];
    }

    byte[] outBytes = new byte[remoteAddrBytes.Length];
    socket.IOControl(
                IOControlCode.RoutingInterfaceQuery, 
                remoteAddrBytes, 
                outBytes);
    for (int i = 0; i < address.Size; i++) {
        address[i] = outBytes[i];
    }

    EndPoint ep = remoteEndPoint.Create(address);
    return (IPEndPoint)ep;
}

次のように使用されます。

IPAddress remoteIp = IPAddress.Parse("192.168.1.55");
IpEndPoint remoteEndPoint = new IPEndPoint(remoteIp, 0);
Socket socket = new Socket(
                      AddressFamily.InterNetwork, 
                      SocketType.Dgram, 
                      ProtocolType.Udp);
IPEndPoint localEndPoint = QueryRoutingInterface(socket, remoteEndPoint );
Console.WriteLine("Local EndPoint is: {0}", localEndPoint);

(ソースコードはこちらからコピー)

IpEndPointポートで を指定していますが、ポートは無関係であることに注意してください。また、返さIpEndPoint.Portれる は常に0です。

于 2014-10-28T15:00:42.397 に答える