首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windows 8- .NET TCP AcceptAsync回调未触发(被Console.ReadLine()阻止)

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

Stack Overflow用户
提问于 2012-09-18 01:19:53
回答 3查看 3.6K关注 0票数 18

我遇到了Windows8和VS2012特有的问题。

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

但是,看起来数据似乎没有进入应用程序堆栈?完全相同的版本在Windows7上运行时没有问题。

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

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

谢谢,

编辑

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

代码语言:javascript
复制
listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

并在与我的服务器应用程序相同的本地IP/端口上侦听。我遇到了同样的问题,我可以远程登录到端口,但listenerSocket.AcceptAsync从未命中。

编辑2个

在进一步的测试中,我的问题与异步套接字调用的使用有关,也就是说,如果我使用像socket.Accept()这样的同步调用,测试应用程序运行正常。但是,当我使用异步套接字调用时,即socket.AcceptAsync(),我遇到了上面提到的问题。到目前为止,我找不到任何提到win7和8在异步套接字调用方面的区别。

这是我的快速示例应用程序,它显示异步回调从未被触发。此代码片段在Windows 7中运行良好,但在Windows 8中不起作用(尝试telnet到127.0.0.1 : 7000)。

代码语言:javascript
复制
    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");
    }
}

编辑3个

我发现还有另外两个人在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 bug,它导致了这个问题并阻塞了异步回调。如果我将代码片段中的Console.ReadLine()替换为:

代码语言:javascript
复制
            while (true)
        {
            System.Threading.Thread.Sleep(10);
        }

一切都很好。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-09-28 15:47:37

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

这是windows8和2012中的一个bug,会影响所有使用AcceptEx和ReadFile的程序。到目前为止,只有这两个功能是已知的影响。

票数 4
EN

Stack Overflow用户

发布于 2012-09-19 22:05:56

我在使用SocketAsyncEventArgs开发Tcp服务器和客户端应用程序时遇到了同样的情况。

我建议你先试试这个。

  1. 打开具有高级安全性的Windows防火墙检查入站/出站规则以查看您的应用程序是否被阻止。
  2. 打开AssemblyInfo.cs并更改

组件: Guid("06985fe3-80eb-48b4-940a-fd926e2f2053")

设置为任何其他GUID值。

通过改变这一点,windows会认为这是一个新的应用程序,如果对旧的应用程序有任何限制,它就不会在新的应用程序上。

票数 0
EN

Stack Overflow用户

发布于 2012-09-19 23:16:50

听起来像这个windows bug,它与Windows8上的IOCP处理(可能只是AcceptEx)有关,而同一线程上的其他阻塞I/O正在进行中:

http://social.technet.microsoft.com/Forums/en-GB/winserver8gen/thread/5764cd0f-fda1-4cfa-ae35-808210bae77e

所以套接字连接被接受了,但是你的应用程序永远不会收到通知。

也许Windows8做了一些奇怪的,稍有破损的巫术,将同步IO如Console.Read内部转换为异步IO。

你可以将你的服务器代码移到不同的线程中,其他的变通方法可能是同步地执行Accept,或者将控制台处理改为异步(我真的不能尝试这样做,因为我没有Windows 8)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12464185

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档