Невозможно сделать 2 параллельных TCP-запроса к одному TCP-клиенту - PullRequest
0 голосов
/ 09 октября 2009

Ошибка: Невозможно прочитать данные из транспортного соединения: операция блокировки была прервана вызовом WSACancelBlockingCall

Положение

  1. Есть TCP-сервер
  2. Мое веб-приложение подключается к этому TCP-серверу

    Используя код ниже:

    TcpClientInfo = new TcpClient();
    _result = TcpClientInfo.BeginConnect(<serverAddress>,<portNumber>, null, null);
    bool success = _result.AsyncWaitHandle.WaitOne(20000, true);
    
    if (!success)
    {
        TcpClientInfo.Close();
        throw new Exception("Connection Timeout: Failed to establish connection.");
    }
    
    NetworkStreamInfo = TcpClientInfo.GetStream();
    NetworkStreamInfo.ReadTimeout = 20000;
    
  3. 2 Пользователи используют одно и то же приложение из двух разных мест для доступа к информации с этого сервера в то же время

  4. Для ответа сервера требуется около 2 секунд
  5. Оба соединяются
  6. Но один из пользователей получает ошибку выше «Невозможно прочитать данные из транспортного соединения: операция блокировки была прервана вызовом WSACancelBlockingCall» при попытке прочитать данные из потока

Как мне решить эту проблему?

  1. Используйте лучший способ подключения к серверу
  2. Не может, потому что это проблема с сервером
    • если проблема с сервером, как сервер должен обрабатывать запрос, чтобы избежать этой проблемы

Ответы [ 2 ]

0 голосов
/ 09 октября 2009

Это выглядит для меня специфично для Windows, что не является моей сильной стороной, но ...

Вы не показываете нам код сервера, только код клиента. Я могу только предположить, что ваш серверный код принимает сокетное соединение, выполняет свою магию, отправляет что-то обратно и закрывает клиентское соединение. Если это ваш случай, тогда это проблема.

Вызов accept () является блокирующим, который ожидает следующую попытку подключения клиента и привязывается к нему. Может быть очередь попыток подключения, созданная и управляемая ОС, но она все еще может принимать только одно подключение за раз.

Если вы хотите иметь возможность обрабатывать несколько одновременных запросов, вам нужно изменить свой сервер на вызов accept (), а когда появится новое соединение, запустить рабочий поток / процесс для обработки запроса и вернуться к верхняя часть цикла, где принимают (). Таким образом, основной цикл передает фактическую работу другому потоку / процессу, чтобы он мог вернуться к бизнесу ожидания следующей попытки подключения.

Реальные серверные приложения более сложны, чем это. Они запускают в пуле кучу «рабочих пчел» потоков / процессов и используют их для будущих запросов. Веб-серверы делают это, например.

Если мои предположения о коде вашего сервера неверны, пожалуйста, сообщите нам, как он выглядит.

0 голосов
/ 09 октября 2009

Просто мысль.

Если вашему серверу требуется 2 секунды для ответа, не должны ли значения времени ожидания быть 2000 вместо 20000 (что составляет 20 секунд)? Первый аргумент для AsyncWaitHandle.WaitOne () указывается в миллисекундах.

Если вы ждете 20 секунд, возможно, ваш сервер отключает вас от ожидания?

...