4

When I compile this code on a machine with Windows 7 Ultimate and .NET 4 installed, it works just fine but when I try it on one with Windows 8 RTM and .NET 4.5 installed, Complete event never fires.

class Program
{
    private static Socket _Socket = new Socket(
        AddressFamily.InterNetwork,
        SocketType.Stream,
        ProtocolType.Tcp);

    private static void Main(string[] args)
    {
        _Socket.Bind(new IPEndPoint(IPAddress.Any, 5012));
        _Socket.Listen(100);

        var arguments = new SocketAsyncEventArgs();
        arguments.Completed += OnAccepted;
        Accept(arguments);

        Console.ReadLine();
    }

    private static void Accept(SocketAsyncEventArgs args)
    {
        args.AcceptSocket = null;
        if (!_Socket.AcceptAsync(args))
            OnAccepted(null, args);
    }

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

The interesting thing here is if I put a breakpoint at this line and debug it:

var arguments = new SocketAsyncEventArgs();

And connect this server using Hercules before continuing execution, it works like a charm. I do this at the start and then magically, OnAccepted gets called and writes "Accepted." to the console on every single connection. I use the same code and same program (Hercules) on the machine with Windows 7 and .NET 4 but it always works.

  • Am I doing something wrong?
  • If not, is it a known bug of my OS or .NET Framework version 4.5?
  • Can anyone reproduce this?

Edit: Both operating systems are 64 bit.
Edit 2: I reported this as a bug on Microsoft Connect, here.
Edit 3: Found a workaround and post it to Connect (Simply by creating a fake, first connection).
Edit 4: If anyone can reproduce this, please join the issue in Connect.
Edit 5: I saw the question Thomas has mentioned and I tested whether Console.ReadLine was causing this or not. Turned out it was. If I add Thread.Sleep(3000) before my Console.ReadLine call and make a connection attempt in 3 seconds after I run the program, it works like a charm. Again, the odd thing is that I need to do this only once before calling Console.ReadLine. If I make one connection before calling Console.ReadLine then every consecutive connection works, even after Console.ReadLine is called. I'll mention this in the Conect page.
Edit 6: I added the link to the other question to the Connect page and added another workaround that involves calling Thread.Sleep before calling Console.ReadLine like I mentioned in the above edit.

Community
  • 1
  • 1
Şafak Gür
  • 7,045
  • 5
  • 59
  • 96
  • Have you checked this isn't just a firewall / etc thing? Does it work with Socket.Accept? (my point here: is the issue with AcceptAsync, or is it with networking generally?) – Marc Gravell Aug 27 '12 at 16:04
  • @Marc: Accept works. AcceptAsync works too, but only if I try to connect _before_ calling AcceptAsync. The weird thing is doing that fixes everyting. All subsequent connections work without a problem if I just put a breakpoint after Listen and before AcceptAsync. When the execution stopped, I just connect to that socket using Hercules and hit F5: Bang, every subsequent connection works like a charm. – Şafak Gür Aug 27 '12 at 16:57
  • I'm not clear on one thing, in the instance where `Completed` never fires, OnAccept is still being called? – Peter Ritchie Sep 14 '12 at 18:04
  • @Peter: No. AcceptAsync returns true so code doesn't call OnAccepted synchronously and new connections doesn't fire the Completed event, so OnAccepted is not being called in that instance. – Şafak Gür Sep 15 '12 at 10:09
  • I'm having the same issue as discussed here: http://stackoverflow.com/questions/12464185/windows-8-issues-with-tcp-sockets-on-local-network-client-server-on-same-mach Will join on Microsoft Connect – TJF Sep 17 '12 at 19:27
  • @Thomas: Thanks, I updated this one after I saw your question and I'm going to update the issue in Connect in a minute. – Şafak Gür Sep 18 '12 at 06:58
  • I'm experiencing the same issue targeting .Net4 with VS2012 and running things on Win8RTM. In order to get AcceptAsync task to complete, I have to activate/switch to the window containing the server process. – Monroe Thomas Nov 08 '12 at 22:10

1 Answers1

1

It turned out to be a Windows 8 bug. Best workaround I could find so far is to start the IOCP operation on a different thread.

So the thing I should do in the code sample that is given in the question is changing this line:

Accept(arguments);

To this line in the Main method:

Task.Run(() => Accept(arguments)).Wait();

This prevents Console.ReadLine() call to block the IOCP operation.

As a side note: This is just a workaround to an operating system bug which will most likely be fixed via an update and -hopefully- making this workaround redundant.

This issue is fixed with the latest version of Windows 8.


Edit: Status of the feedback item I have posted in Connect is changed to "By Design".
I also received an e-mail which contains the following:

The underlying issue for this behavior has to do with how IO Completion Ports are handled in Windows 8. .NET works using the completion ports; when their behavior changed, so did the .NET behavior.

Edit 2: Status of the feedback is changed again to "Active" with no details.

Edit 3: The feedback received another answer from Microsoft, stating:

The latest version of Windows 8 should have this fixed. Note that it's an OS issue, not a .NET issue: you need to make sure you have the latest version of the OS. No changes were made to .NET to either cause or fix this issue."

Şafak Gür
  • 7,045
  • 5
  • 59
  • 96
  • 1
    is there an official Microsoft bug report that anyone could track publicly? – mizi_sk Jan 07 '13 at 13:05
  • @mizi_sk: There is none I could find. I found a MS Connect link that's mentioned in [this TechNet Forum post](http://social.technet.microsoft.com/Forums/en-US/winserver8gen/thread/5764cd0f-fda1-4cfa-ae35-808210bae77e) but it doesn't work anymore. In the same page Len Holgate commented the Microsoft's response as "We've passed this to the base OS team and they will consider this for a future update. I'm resolving this postponed." so there is no exact date or an active bug report to track afaik. – Şafak Gür Jan 08 '13 at 07:13
  • @mizi_sk: They closed the case, saying that this behavior is by design. – Şafak Gür Feb 27 '13 at 12:51
  • @mizi_sk: The issue is fixed with an update to Windows 8. I've edited the answer with the details. – Şafak Gür Nov 02 '13 at 11:20