所以我现在已经获得了这个例外大约一个星期了,我终于设法将它转变为一个易于阅读的代码片段。
作为背景,我正在为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)
非常感谢任何线索。
答案 0 :(得分:4)
使用新的WinRT套接字类型,正确编程套接字比以往任何时候都容易,但不要搞错:它们仍然是复杂的野兽。
“强制关闭”(WSAECONNRESET / 10054)错误是指远程端(在本例中为客户端)中止其连接,它通过部署StreamSocket
来实现。这被报告为错误,但并不罕见,应该优雅地处理。即,如果服务器已经发送了所有数据并且只是在等待接收更多(可选)数据,那么它应该将WSAECONNRESET视为常规关闭。
提示:如果您将Exception.HResult
传递给SocketError.GetStatus
,则应该会看到SocketErrorStatus.ConnectionResetByPeer
。这样,您就可以在错误处理代码中避免使用魔术值。
P.S。我a blog post描述了一些更常见的套接字错误和套接字错误处理。