Подтвердить что ты не робот

Windows 8 -.NET TCP AcceptAsync callback не запускается (заблокирован Console.ReadLine())

У меня возникла проблема, связанная с 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

При последующем тестировании он обнаруживает, что моя проблема имеет какое-то отношение к использованию вызовов сокета Async, то есть если я использую синхронные вызовы типа socket.Accept(), тестовое приложение работает нормально. Однако, когда я использую вызовы сокета Async, то есть 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");
    }
}

РЕДАКТИРОВАТЬ 3

Я обнаружил, что еще 2 человека сообщали об одной и той же проблеме в Microsoft Connect: 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

В то время как второй интересен, поскольку, как представляется, в вызове Console.ReadLine() возникает ошибка Windows, и это вызывает проблему и блокирует обратный вызов async. Если я заменил Console.ReadLine() в своем фрагменте с помощью:

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

все работает нормально.

4b9b3361

Ответ 2

Я встречаю то же самое, когда разрабатывал серверные и клиентские приложения Tcp с помощью SocketAsyncEventArgs

Я предлагаю вам попробовать это первым.

  • открыть брандмауэр Windows с расширенной безопасностью проверьте входящие/исходящие правила, чтобы узнать, заблокировано ли ваше приложение.

  • откройте AssemblyInfo.cs и измените

[сборка: Guid ( "06985fe3-80eb-48b4-940a-fd926e2f2053" )]

для любого другого значения guid.

Изменив это, окна подумают, что это новое приложение, и если есть какие-либо ограничения для старого приложения, оно не будет на новом.

Ответ 3

Звучит как эта ошибка Windows, связанная с обработкой IOCP (возможно, только AcceptEx) в Windows 8, в то время как в этом же потоке выполняется другой блокирующий ввод-вывод:

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

Итак, соединение сокета принято, но ваше приложение никогда не получает уведомления об этом.

Возможно, Windows 8 делает некоторые странные, слабые сломанные, voodoo для преобразования синхронного ввода-вывода, такого как Console.Read in async внутренне.

Вы можете просто переместить код сервера в другой поток, другие способы обхода, чтобы попытаться выполнить синхронизацию Accept или изменить обработку консоли как асинхронную (я не могу попробовать, поскольку у меня нет Windows 8).