关闭连接时出现WindowsRT StreamSocket异常

时间:2012-12-18 20:07:58

标签: c# sockets async-await

所以我现在已经获得了这个例外大约一个星期了,我终于设法将它转变为一个易于阅读的代码片段。

作为背景,我正在为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)

非常感谢任何线索。

1 个答案:

答案 0 :(得分:4)

使用新的WinRT套接字类型,正确编程套接字比以往任何时候都容易,但不要搞错:它们仍然是复杂的野兽。

“强制关闭”(WSAECONNRESET / 10054)错误是指远程端(在本例中为客户端)中止其连接,它通过部署StreamSocket来实现。这被报告为错误,但并不罕见,应该优雅地处理。即,如果服务器已经发送了所有数据并且只是在等待接收更多(可选)数据,那么它应该将WSAECONNRESET视为常规关闭。

提示:如果您将Exception.HResult传递给SocketError.GetStatus,则应该会看到SocketErrorStatus.ConnectionResetByPeer。这样,您就可以在错误处理代码中避免使用魔术值。

P.S。我a blog post描述了一些更常见的套接字错误和套接字错误处理。