4

サーバー側でUdpClientを使用していて、クライアント側(複数のクライアント)にデータを送信しています。endRecieveまたはbeginRecieveを呼び出すと、クライアントがudpポートでのリッスンを突然停止し、サーバーがSocketExceptionでヒットします。

私の理解では、これは「ICMP宛先に到達できない」ためであり、サーバーにポートが閉じていることを通知しているだけです。それは問題ありませんが、SocketExceptionsのどちらもそれがどのエンドポイントからのものであるかを教えてくれません。

サーバーがエンドポイントへの送信を停止し、さらに多くのSocketExceptionが発生するように、どのエンドポイントが閉じられているかを知るにはどうすればよいですか?

または、UdpclientがこれらのSocketExceptionsのスローを停止する方法があります。これにより、クライアントが数秒後に応答しない場合にクライアントをタイムアウトさせることができます。

4

1 に答える 1

0

私は同じ問題を自分で扱っているので、誰かがより良い解決策を思い付くかどうかを知りたいと思いますが、今のところ私はいくつかのアイデアを持っています:

ソケットの周りにcommラッパークラス(これを呼びましょうAsyncComm)があり、構築時に所有者クラスから例外ハンドラーデリゲートが渡されます。例外ハンドラーデリゲートは、例外の引数と、例外をスローしたAsyncCommインスタンスへの参照を受け取ります。それから私は置きます

try
{
   // Do stuff here
{
catch (Exception e)
{
   CallExceptionHandlerDelegate(e, this);
}

の各非同期ハンドラーメソッドでAsyncComm、例外をチェーンの上位にスローできるようにします。私の場合、例外ハンドラーはインスタンスへの参照を使用してAsyncCommインスタンス内のメソッドを呼び出し、AsyncCommソケットを再初期化するように指示します。その動作を、継続的に取得するのを停止するために必要なものに変更できますSocketExceptions

例外が発生したエンドポイントの決定に関して、私が今持っている唯一のアイデアは、SocketException.Message文字列の終わりからエンドポイントを解析することですが、それはかなりの恨みのようです。

更新:それは応急修理ですが、動作します。以下のコードを解析してください。その一部はこの質問から引用したものです。

private IPEndPoint parseEndPointFromString(string input)
{
    // Matches 1-255.1-255.1-255.1-255:0-65535. I think.
    const string IPPortRegex = @"(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?):(6553[0-5]|655[0-2]\d|65[0-4]\d\d|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}|0)";

    Match match = Regex.Match(input, IPPortRegex);

    if (match.Success)
    {
        string IPPortString = match.Value;

        string[] ep = IPPortString.Split(':');
        if (ep.Length != 2) throw new FormatException("Invalid endpoint format");
        IPAddress ip;
        if (!IPAddress.TryParse(ep[0], out ip))
        {
            throw new FormatException("Invalid IP address");
        }
        int port;
        if (!int.TryParse(ep[1], out port))
        {
            throw new FormatException("Invalid port");
        }
        return new IPEndPoint(ip, port);
    }
    else
    {
        throw new FormatException("Invalid input string, regex could not find an IP:Port string.");
    }
}
于 2011-06-30T14:46:10.160 に答える