2

そのため、この例外が発生してから約 1 週間が経ちましたが、ようやく読みやすいコード スニペットにまとめることができました。

背景として、私は Windows RT 用のアプリをプログラミングしており、基本的なソケットを使用しようとしています。

テストのために、サーバーとして機能するローカル ソケット リスナーを作成しました。サーバーとクライアントの両方がソケットで読み書きできる必要があります。

クライアントもサーバーも、ネットワークを介してどのくらいのデータが送信されるかを知ることはできません (または知る必要はありません)。これは絶対条件です。サーバーは、オンデマンドで任意の量のデータを処理できる必要があります。

ここに例があります。単体テストとして提示されているのは、それが一貫してエラーに遭遇する場所だからです。この例から 1 行を削除すると、エラーが解消されます。

    [TestMethod]
    public async Task TestSomething()
    {
        //  Setup local server
        //
        StreamSocketListener listener = new StreamSocketListener();
        listener.ConnectionReceived += async (sender, args) =>
        {
            DataReader serverReader = new DataReader(args.Socket.InputStream);
            await serverReader.LoadAsync(4096);   //  <-- Exception on this line
        };

        await listener.BindServiceNameAsync("10181");

        //  Setup client
        //
        using (StreamSocket socket = new StreamSocket())
        {
            await socket.ConnectAsync(new HostName("localhost"), "10181");

            DataReader reader = new DataReader(socket.InputStream);
            Task readTask = Listen(reader);
        }
    }

    public async Task Listen(DataReader reader)
    {
        await reader.LoadAsync(4096);
    }

サーバーが を呼び出す行で例外が発生しLoadAsync(...)、単体テストが終了すると例外がスローされます。

例外は(一見)単純です。

既存の接続がリモート ホストによって強制的に閉じられました。(HRESULT からの例外: 0x80072746)

手がかりは大歓迎です。

4

1 に答える 1

4

新しい WinRT ソケット タイプを使用すると、ソケットを正しくプログラミングするのがこれまでになく簡単になりますが、間違いなく、それらは依然として複雑な獣です。

「強制終了」(WSAECONNRESET / 10054) エラーは、リモート側 (この場合はクライアント) が接続を中止したときに発生しますStreamSocket。これはエラーとして報告されますが、珍しいことではなく、適切に処理する必要があります。つまり、サーバーがすべてのデータを送信し、さらに (オプションの) データを受信するのを待っている場合、WSAECONNRESET を通常の終了として処理する必要があります。

ヒント: に渡すException.HResultSocketError.GetStatus、それがSocketErrorStatus.ConnectionResetByPeer. そうすれば、エラー処理コードでマジック値を回避できます。

PSより一般的なソケット エラーのいくつかと一般的なソケット エラー処理について説明したブログ投稿があります。

于 2012-12-18T21:46:31.790 に答える