使用System.Net.Sockets.Socket.AcceptAsync模型时堆栈溢出 [英] Stack overflow when using the System.Net.Sockets.Socket.AcceptAsync model

查看:631
本文介绍了使用System.Net.Sockets.Socket.AcceptAsync模型时堆栈溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于C#和.NET的 System.Net.Sockets.Socket.AcceptAsync 方法,一会需要处理,以处理假的立即可用的SocketAsyncEventArgs <返回值为/ code>从同步进行连接状态。微软提供的例子(上找到 System.Net.Sockets.SocketAsyncEventArgs 类页),这将导致堆栈溢出,如果有大量挂起连接,它可以被利用在实现其处理模型的任何系统。

With respect to C# and .NET's System.Net.Sockets.Socket.AcceptAsync method, one would be required to handle a return value of "false" in order to handle the immediately available SocketAsyncEventArgs state from the synchronously processed connection. Microsoft provides examples (found on the System.Net.Sockets.SocketAsyncEventArgs class page) which will cause a stack overflow if there are a large amount of pending connections, which can be exploited on any system that implements their handling model.

为解决此问题越来越其它的想法是做一个循环调用处理方法,用条件是该值 Socket.AcceptAsync 返回等于假的,并打破循环(允许延迟处理),如果该值指示该操作被完成异步(真)。然而,这种解决方案还导致因为事实上一个堆栈溢出漏洞,使用的SocketAsyncEventArgs 传递给 Socket.AcceptAsync 有在方法的末尾,以 Socket.AcceptAsync ,它也有立即可用一个循环呼叫,同步接受连接。

Other ideas for getting around this issue are to make a loop that calls the handler method, with the condition being that the value Socket.AcceptAsync returns is equal to false, and to break the loop (to allow deferred processing) if the value is indicating that the operation is being completed asynchronously (true). However, this solution also causes a stack overflow vulnerability because of the fact that the callback associated with the SocketAsyncEventArgs passed to Socket.AcceptAsync has at the end of the method, a call to Socket.AcceptAsync, which also has a loop for immediately available, synchronously accepted, connections.

正如你所看到的,这是一个非常坚实的问题,我还没有找到,不涉及一个很好的解决方案的System.Threading .ThreadPool 和创造万吨其他方法和调度处理。据我所看到的,与 Socket.AcceptAsync Socket异步模式需要比什么是表现在MSDN上的例子更多。

As you can see, this is a pretty solid problem, and I've yet to find a good solution that does not involve System.Threading.ThreadPool and creating tons of other methods and scheduling processing. As far as I can see, the asynchronous socket model relating to Socket.AcceptAsync requires more than what is demonstrated in the examples on MSDN.

有没有人有一个廉洁高效的解决方案,以处理那些从Socket.AcceptAsync同步接受没有进入创建单独的线程来处理连接,无需使用递归?

Does anyone have a clean and efficient solution to handling immediately pending connections that are accepted synchronously from Socket.AcceptAsync without going into creating separate threads to handle the connections and without utilizing recursion?

推荐答案

我不会用 AcceptAsync方法,而 BeginAccept / EndAccept ,并正确执行普通异步模式,也就是检查 CompletedSynchronously 来避免回调中。在其完成的操作回调线

I wouldn't use AcceptAsync, but rather BeginAccept/EndAccept, and implement the common async pattern correctly, that is, checking for CompletedSynchronously to avoid callbacks in the callback thread on operations which completed .

另请参阅的http:/ /stackoverflow.com/questions/1372053/asynccallback-completedsynchronously

有关规定使用<编辑code> AcceptAsync方法

MSDN文档明确地说,回调将不会被调用为它同步完成操作。这是那里的回调总是调用通用异步模式不同。

The MSDN documentation explicitly says that the callback will NOT be invoked for operations which completed synchronously. This is different to the common async pattern where the callback is always invoked.

如果在I / O操作
返回true悬而未决。在
SocketAsyncEventArgs.Completed事件
e参数将在操作
完成筹集。返回
假,如果I / O操作完成
同步。在
e参数SocketAsyncEventArgs.Completed事件
将不会引发
和作为一个参数
通过电子对象可在
方法调用返回后立即检查检索操作的
的结果。

Returns true if the I/O operation is pending. The SocketAsyncEventArgs.Completed event on the e parameter will be raised upon completion of the operation. Returns false if the I/O operation completed synchronously. The SocketAsyncEventArgs.Completed event on the e parameter will not be raised and the e object passed as a parameter may be examined immediately after the method call returns to retrieve the result of the operation.

我目前看不出循环不会解决堆栈溢出问题。 ?也许你可以在引起该问题的代码更具体

I currently don't see how a loop would not solve the stack overflow issue. Maybe you can be more specific on the code that causes the problem?

编辑2:我在想这样的代码这(仅关于 AcceptAsync方法,剩下的只是为了得到一个工作程序与尝试一下):

Edit 2: I'm thinking of code like this (only in regard to AcceptAsync, the rest was just to get a working app to try it out with):

static void Main(string[] args) {
    Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    listenSocket.Bind(new IPEndPoint(IPAddress.Loopback, 4444));
    listenSocket.Listen(100);
    SocketAsyncEventArgs e = new SocketAsyncEventArgs();
    e.Completed += AcceptCallback;
    if (!listenSocket.AcceptAsync(e)) {
        AcceptCallback(listenSocket, e);
    }
    Console.ReadKey(true);
}

private static void AcceptCallback(object sender, SocketAsyncEventArgs e) {
    Socket listenSocket = (Socket)sender;
    do {
        try {
            Socket newSocket = e.AcceptSocket;
            Debug.Assert(newSocket != null);
            // do your magic here with the new socket
            newSocket.Send(Encoding.ASCII.GetBytes("Hello socket!"));
            newSocket.Disconnect(false);
            newSocket.Close();
        } catch {
            // handle any exceptions here;
        } finally {
            e.AcceptSocket = null; // to enable reuse
        }
    } while (!listenSocket.AcceptAsync(e));
}

这篇关于使用System.Net.Sockets.Socket.AcceptAsync模型时堆栈溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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