Задать вопрос
  • Как наладить обмен данными между клиентом и сервером?

    AlexanderYudakov
    @AlexanderYudakov
    C#, 1С, Android, TypeScript
    1. Убрать все "lock" - никакой пользы от них здесь нет.

    2. Убрать все "try {...} catch (Exception e) { Debug.Print(e.Message); }
    Никакой пользы от них тоже нет.

    3. Убрать IsCorrect. Читаем длину сообщения, затем читаем нужное количество байт. А то, что вы называете "Фактическая длина" - плод вашей фантазии.

    4. Читать надо ни до тех пор, пока DataAvailable, а до тех пор, пока не будет получено нужное количество байт. Синхронно, либо асинхронно вы это будете делать - без разницы.

    5. А теперь собственно ответ на ваш вопрос:
    Механизм чтения сообщений умирает, когда читатель читает быстрее, чем писатель пишет (либо сеть передает). В этом случае DataAvailable вернет false; ваш алгоритм, вместо того, чтобы дождаться оставшейся части сообщения, прерывает чтение на середине сообщения, говорит, что IsCorrect() == false, и зависает.

    6. Формат сообщения имеет смысл упростить: первые 4 байта - длина тела в байтах; затем само тело (например, в UTF-8, если вам нужен текст). Соответственно, читаем сначала 4 байта, а потом еще столько, сколько там указано.

    P.S.
    7. Вызывать Encoding.GetString() следует только на целом сообщении; если вы делаете это на части сообщения - результат непредсказуем.

    8. Сетевые исключения обрабатывать, конечно же, надо. Однако Debug.Print - это не решение проблемы. Сокет имеет смысл закрыть. А дальше - либо уведомить об этой проблеме своего клиента (кто обрабатывает полученные сообщения), либо, по-хорошему, - попытаться открыть другое соединение и повторить попытку продолжить работу так, чтобы клиент ничего не заметил :)
    Ответ написан
    Комментировать