WSAEventSelect模型 [英] WSAEventSelect model

查看:335
本文介绍了WSAEventSelect模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿,我使用WSAEventSelect事件通知套接字。到目前为止,一切都很酷,工作像一个魅力,但有一个问题。

Hey I'm using the WSAEventSelect for event notifications of sockets. So far everything is cool and working like a charm, but there is one problem.

客户端是一个.NET应用程序,服务器是用Winsock C ++编写的。在.NET应用程序中,我使用System.Net.Sockets.Socket类为TCP / IP。当我调用Socket.Shutdown()和Socket.Close()方法,我收到服务器中的FD_CLOSE事件,我相信是很好。当我检查我传递给WSAEnumNetworkEvents的WSANETWORKEVENTS的iErrorCode时,问题发生。我检查它像这样

The client is a .NET application and the server is written in Winsock C++. In the .NET application I'm using System.Net.Sockets.Socket class for TCP/IP. When I call the Socket.Shutdown() and Socket.Close() method, I receive the FD_CLOSE event in the server, which I'm pretty sure is fine. Okay the problem occurs when I check the iErrorCode of WSANETWORKEVENTS which I passed to WSAEnumNetworkEvents. I check it like this

if (listenerNetworkEvents.lNetworkEvents & FD_CLOSE)
    {
    	if (listenerNetworkEvents.iErrorCode[FD_CLOSE_BIT] != 0)
    	{
    		// it comes here
    		// which means there is an error
    		// and the ERROR I got is
    		// WSAECONNABORTED
    		printf("FD_CLOSE failed with error %d\n", 
    			listenerNetworkEvents.iErrorCode[FD_CLOSE_BIT]);
    		break;
    	}

    	closesocket(socketArray[Index]);
}

但它失败,并出现 WSAECONNABORTED 错误。为什么会这样?

But it fails with the WSAECONNABORTED error. Why is that so?

编辑: Btw,我在同一台计算机上运行客户端和服务器,是因为?我收到了FD_CLOSE事件,当我这样做:

Btw, I'm running both the client and server on the same computer, is it because of that? And I received the FD_CLOSE event when I do this:

server.Shutdown(SocketShutdown.Both);   // in .NET C#, client code


推荐答案

猜测你正在调用Shutdown(),然后立即关闭()。这将给你所看到的症状,因为这是砰击连接关闭。 Shutdown()确实发起了一个正常的断开连接(TCP FIN),但是紧随它之后Close()中止,向远程对等体发送一个TCP RST数据包。

I'm guessing you're calling Shutdown() and then Close() immediately afterward. That will give the symptom you're seeing, because this is "slamming the connection shut". Shutdown() does initiate a graceful disconnect (TCP FIN), but immediately following it with Close() aborts that, sending a TCP RST packet to the remote peer. Your Shutdown(SocketShutdown.Both) call slams the connection shut, too, by the way.

正确的模式是:


  1. 调用Shutdown()将direction参数设置为write,这意味着我们不会再向远程对等端发送任何数据。这会导致堆栈发送TCP FIN数据包。

  1. Call Shutdown() with the direction parameter set to "write", meaning we won't be sending any more data to the remote peer. This causes the stack to send the TCP FIN packet.

回到等待Winsock事件。当远程对等体也完成写入时,它也将调用Shutdown(write),导致其堆栈向您的机器发送TCP FIN数据包,并为您的应用程序获取FD_CLOSE事件。

Go back to waiting for Winsock events. When the remote peer is also done writing, it will call Shutdown("write"), too, causing its stack to send your machine a TCP FIN packet, and for your application to get an FD_CLOSE event. While waiting, your code should be prepared to continue reading from the socket, because the remote peer might still be sending data.



在等待期间,您的代码应准备好继续从套接字读取,因为远程对等端可能仍在发送数据。 p>(请原谅上面的伪C#,我不会说.NET,只有C ++。)

(Please excuse the pseudo-C# above. I don't speak .NET, only C++.)

两个对等体都应该使用同样的关闭模式:each告诉另一个当它完成写入,然后等待接收远程对等体在它关闭套接字之前完成写入的通知。

Both peers are expected to use this same shutdown pattern: each tells the other when it's done writing, and then waits to receive notification that the remote peer is done writing before it closes its socket.

重要的是要实现的是TCP是一种双向协议:每侧可以独立发送和接收其他。关闭套接字读取不是一件好事。这就像和另一个人谈话,只是说话和不愿意听。正常关机协议说,我已经说完了,我要等到你停止说话之前我走开。

The important thing to realize is that TCP is a bidirectional protocol: each side can send and receive independently of the other. Closing the socket to reading is not a nice thing to do. It's like having a conversation with another person but only talking and being unwilling to listen. The graceful shutdown protocol says, "I'm done talking now. I'm going to wait until you stop talking before I walk away."

这篇关于WSAEventSelect模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆