18

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);

サーバーアプリケーションと同じローカルIP /ポートでリッスンします。同じ問題が発生しています。ポートに telnet で接続できますが、listenerSocket.AcceptAsync はヒットしません。

編集2

さらにテストすると、問題が非同期ソケット呼び出しの使用に関係していることがわかりました。つまり、socket.Accept() のような同期呼び出しを使用すると、テスト アプリケーションは正常に実行されます。ただし、非同期ソケット呼び出し、つまり socket.AcceptAsync() を使用すると、前述の問題が発生します。これまでのところ、非同期ソケット呼び出しに関する win7 と 8 の違いについての言及は見つかりませんでした。

これは、非同期コールバックがトリガーされないことを示す簡単なサンプル アプリです。このスニペットは Windows 7 では問題なく動作しますが、Windows 8 では動作しません (127.0.0.1 : 7000 に telnet で接続してみてください)。

    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 で同じ問題を報告している他の 2 人を見つけました: https://connect.microsoft.com/VisualStudio/feedback/details/759913/socketasynceventargs-completed-doesnt-fire-in-net-framework-4-5 および http: //connect.microsoft.com/VisualStudio/feedback/details/747218/saea-not-working-in-net-4-5-rp

2 つ目は、Console.ReadLine() 呼び出しに Windows のバグがあり、それが問題を引き起こし、非同期コールバックをブロックしていると結論付けているように見えるため、興味深いものです。スニペットの Console.ReadLine() を次のように置き換えると:

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

すべて正常に動作します。

4

3 に答える 3

4

これを参照してください:最初に IO を発行したスレッドが Windows 8 の ReadFile でブロックされている場合、GetQueuedCompletionStatus は IOCP から IO をデキューできません

これは Windows 8 および 2012 のバグであり、AcceptEx および ReadFile を使用するすべてのプログラムに影響します。現在のところ、これら 2 つの機能のみが影響を受けることが知られています。

于 2012-09-28T07:47:37.250 に答える
0

同じスレッドで他のブロッキングI/Oが進行中の場合、Windows 8でのIOCP処理(おそらくAcceptExのみ)に関連するこのWindowsのバグのように聞こえます。

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

したがって、ソケット接続は受け入れられますが、アプリはその通知を受信しません。

たぶん、Windows 8は、Console.Readのような同期IOを内部で非同期に変換するために、奇妙で少し壊れたブードゥーを実行します。

サーバーコードを別のスレッドに移動することもできます。他の回避策として、Acceptを同期的に実行するか、コンソール処理を非同期に変更することがあります(Windows 8がないため、実際には試すことができません)。

于 2012-09-19T15:16:49.800 に答える
0

SocketAsyncEventArgsを使用してTcpサーバーとクライアントアプリケーションを開発していたときに同じことを満たしています

最初にこれを試してみることをお勧めします。

  1. 高度なセキュリティでWindowsファイアウォールを開き、インバウンド/アウトバウンドルールをチェックして、アプリケーションがブロックされているかどうかを確認します。

  2. AssemblyInfo.csを開き、

[アセンブリ:Guid( "06985fe3-80eb-48b4-940a-fd926e2f2053")]

他のGUID値に。

これを変更することにより、Windowsはこれが新しいアプリケーションであると見なし、古いアプリケーションに制限があった場合、新しいアプリケーションには適用されません。

于 2012-09-19T14:05:55.737 に答える