Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows 8 - .NET TCP AcceptAsync callback not firing (blocked by Console.ReadLine())

I'm experiencing an issue specific to Windows 8 and VS2012.

I have a TCP socket server and client and am doing some testing on the local network. With sysinternals TCPView, I can see that packets are sent from the TCP client and arrive at the TCP Server (I see the packet counters increase).

However, it appears as if the data is not making it to the application stack? The very same build runs without issues on Windows 7.

I have the Windows 8 firewall turned off and run both process with elevated permissions on a domain admin users with UAC turned off.

When I connect the client to a an outside server (running on a separate machine), everything works fine. Is there anything else in Windows 8 that could prohibit TCP data communication between local processes?

Thanks,

EDIT

To make sure nothing in my server application is causing this issue, I built a quick TCP server in a console application, with the following code for the socket constructor:

listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

and listen on the same local IP/Port as my server application. I'm experiencing the same issue, I can telnet to the port but listenerSocket.AcceptAsync is never hit.

EDIT 2

Upon further testing, it appers my issue has something to do with the use of the Async socket calls, i.e. if I use the synchronous calls like socket.Accept(), the test application is performing normally. However, when I use Async socket calls, i.e. socket.AcceptAsync(), I'm experiencing the issues mentioned. So far I couldn't find any mention of differences between win7 & 8 in regards to async socket calls.

Here's my quick sample app that shows that the async callback is never triggered. This snippet works fine in Windows 7 but does not work in Windows 8 (try to telnet to 127.0.0.1 : 7000).

    class Program
{
    private static SocketAsyncEventArgs socketAsyncEventArgs = new SocketAsyncEventArgs();

    static void Main(string[] args)
    {
        var listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        listenerSocket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 7000));
        listenerSocket.Listen(100);

        socketAsyncEventArgs.Completed += AcceptEventArg_Completed;
        listenerSocket.AcceptAsync(socketAsyncEventArgs);

        Console.ReadLine();
    }

    private static void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
    {
        Console.WriteLine("AcceptEventArg_Completed");
    }
}

EDIT 3

I found 2 others reporting the same issue on Microsoft Connect: https://connect.microsoft.com/VisualStudio/feedback/details/759913/socketasynceventargs-completed-doesnt-fire-in-net-framework-4-5 and http://connect.microsoft.com/VisualStudio/feedback/details/747218/saea-not-working-in-net-4-5-rp

Whereas the 2nd one is interesting as it seems to conclude there is a Windows bug in the Console.ReadLine() call and it is causing the issue and blocking the async callback. If I replace Console.ReadLine() in my snippet with:

            while (true)
        {
            System.Threading.Thread.Sleep(10);
        }

everything works fine.

like image 425
TJF Avatar asked Sep 17 '12 17:09

TJF


1 Answers

See this: GetQueuedCompletionStatus can't dequeue IO from IOCP if the thread which originally issued the IO is blocking in ReadFile under windows 8

It's a bug in windows 8 and 2012 and affect all programs which used AcceptEx and ReadFile. As for now, only these two functions are known affected.

like image 169
czz Avatar answered Oct 29 '22 18:10

czz