可以将臭名昭着的"ERROR_NETNAME_DELETED"错误视为错误吗?

Mar*_*cci 5 c++ winapi network-programming tcp iocp

我正在使用完成端口在Windows NT中编写tcp服务器以利用异步I/O. 我有一个TcpSocket类,一个TcpServer类和一些(虚函数)回调在I/O操作完成时调用,例如onRead()用于读取完成时.我在建立连接时也有onOpen(),在连接关闭时也有onEof(),依此类推.我总是有套接字的挂起读取,所以如果套接字有效地获取数据(读取将完成大小> 0)它调用onRead(),而不是客户端客户端关闭套接字(读取将是完成大小== 0)它调用onEof(),服务器知道客户端何时用closesocket(server_socket)关闭套接字; 从它的角度来看.

一切都优雅,但我注意到了一件事:

当我调用closesocket(client_socket); 在连接的服务器端端点,而不是客户端端(设置为linger {true,0}或不设置),挂起的读取将完成为错误,即读取大小不仅是== 0,但GetLastError()也返回错误:64,或'ERROR_NETNAME_DELETED'.我在网上搜索了很多这个,但没有发现任何有趣的东西.

然后我问自己:但这是一个真正的错误吗?我的意思是,这真的可以被视为错误吗?

问题是在服务器端,当我关闭socket(client_socket)时,将调用onError()回调; 而不是onEof().所以我想这个:

如果我收到此'ERROR_NETNAME_DELETED'"错误",请调用onEof()而不是onError()?会引入一些错误或未定义的行为吗?让我问这个问题的另一个重点是:

当我通过'ERROR_NETNAME_DELETED'收到此读取完成时,我检查了OVERLAPPED结构,特别是包含底层驱动程序的NTSTATUS错误代码的overlapped-> Internal参数.如果我们看到一个NTSTATUS错误代码列表[ http://www.tenox.tc/links/ntstatus.html ],我们可以清楚地看到'ERROR_NETNAME_DELETED'是由NTSTATUS 0xC000013B生成的,这是一个错误,但它是称为"STATUS_LOCAL_DISCONNECT".好吧,它看起来不像是错误的名称.看起来更像是"ERROR_IO_PENDING"这是一个错误,但也是一个正确行为的状态.

那么检查OVERLAPPED结构的Internal参数怎么样呢?当这是==到'STATUS_LOCAL_DISCONNECT'时,会执行对onEof()回调的调用?会弄得一团糟吗?

另外,我必须说,从服务器端,如果我在调用closesocket(client_socket)之前调用DisconnectEx(); 我不会收到那个错误.但是我不想叫DisconnectEx()呢?例如,当服务器关闭并且不想等待所有DisconnectEx()完成时,但只想关闭所有客户端的连接.

Dav*_*nan 3

如何处理错误情况完全取决于您。在您的情况下,这种错误情况完全是可以预料的,并且您将其视为预期情况是完全安全的。

这种性质的另一个例子是当您调用 API 函数但不知道要提供多大的缓冲区时。因此,您提供了一个您希望足够大的缓冲区。但如果 API 调用失败,您将检查最后一个错误是否为ERROR_INSUFFICIENT_BUFFER。这是预期的错误情况。然后您可以使用更大的缓冲区重试。