Windows 8 - .NET TCP AcceptAsync回调未触发(由Console.ReadLine()阻止)

TJF*_*TJF 18 c# tcp windows-8 visual-studio-2012

我遇到了Windows 8和VS2012特有的问题.

我有一个TCP套接字服务器和客户端,我正在本地网络上进行一些测试.使用sysinternals TCPView,我可以看到数据包是从TCP客户端发送到达TCP服务器的(我看到数据包计数器增加).

但是,好像数据没有进入应用程序堆栈?在Windows 7上,完全相同的构建运行没有问题.

我关闭了Windows 8防火墙,并在关闭UAC的域管理员用户上使用提升的权限运行这两个进程.

当我将客户端连接到外部服务器(在单独的机器上运行)时,一切正常.Windows 8中是否还有其他可以禁止本地进程之间的TCP数据通信的内容?

谢谢,

编辑

为了确保我的服务器应用程序中没有任何内容导致此问题,我在控制台应用程序中构建了一个快速TCP服务器,其中包含以下用于套接字构造函数的代码:

listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Run Code Online (Sandbox Code Playgroud)

并在与我的服务器应用程序相同的本地IP /端口上侦听.我遇到了同样的问题,我可以telnet到端口但是listenerSocket.AcceptAsync永远不会被击中.

编辑2

在进一步测试时,我认为我的问题与使用Async套接字调用有关,即如果我使用像socket.Accept()这样的同步调用,则测试应用程序正常运行.但是,当我使用异步套接字调用,即socket.AcceptAsync()时,我遇到了上述问题.到目前为止,我找不到任何关于异步套接字调用的win7和8之间的差异.

这是我的快速示例应用程序,它显示异步回调从未被触发.此代码段在Windows 7中正常工作,但在Windows 8中不起作用(尝试telnet到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");
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑3

我发现其他2个人在Microsoft Connect上报告了同样的问题:https: //connect.microsoft.com/VisualStudio/feedback/details/759913/socketasynceventargs-completed-doesnt-fire-in-net-framework-4-5http: //connect.microsoft.com/VisualStudio/feedback/details/747218/saea-not-working-in-net-4-5-rp

而第二个是有趣的,因为它似乎总结在Console.ReadLine()调用中有一个Windows错误,它导致问题并阻止异步回调.如果我用我的代码段替换Console.ReadLine():

            while (true)
        {
            System.Threading.Thread.Sleep(10);
        }
Run Code Online (Sandbox Code Playgroud)

一切正常.

czz*_*czz 4

请参阅:如果最初发出 IO 的线程在 Windows 8 下的 ReadFile 中阻塞,则 GetQueuedCompletionStatus 无法将 IO 从 IOCP 中出列

这是 Windows 8 和 2012 中的一个错误,影响所有使用 AcceptEx 和 ReadFile 的程序。目前,已知只有这两个功能受到影响。