2

所以我已经收到这个异常大约一个星期了,我终于设法把它变成了一个可以轻松阅读的代码片段。

作为背景,我正在为 Windows RT 编写应用程序,并且正在尝试使用基本套接字。

为了测试,我创建了一个本地套接字侦听器来充当服务器。服务器和客户端都需要能够在套接字上读/写。

客户端和服务器都不能(或不应该)知道有多少数据将通过网络(如果有的话)。这是一个绝对的要求。服务器应该能够按需处理任意数量的数据。

这是一个例子。它以单元测试的形式呈现,仅仅是因为那是我一直遇到错误的地方。从此示例中删除任何单行都会导致错误消失:

    [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 回答