Исходя из показанного кода, вполне ожидаемо иногда получить пустую полезную нагрузку, потому что, если пакеты полезной нагрузки еще не поступили: inFromDotNet.available()
будет равно нулю.
По сути, .available()
(и эквивалент) следует никогда использовать для определения чего-либо о содержимом, кроме «есть байты, буферизируемые в настоящее время» (возможно, для выбора между синхронизированным чтением и асинхронным чтением).
Здесь обычно используются два подхода:
- используйте EOF для указания конца полезной нагрузки, то есть читайте до тех пор, пока сокет не скажет, что он закрыт и все прочитано ; как это определить, зависит от конкретного API сокета (например, в .NET это будет, когда
Receive
возвращает неположительное число)
- реализовать какой-то базовый протокол кадрирования
Первый вариант актуален, если вы будете отправлять только одно сообщение на сокет; вторая опция необходима , если вы будете отправлять несколько сообщений на сокет. Базовый протокол кадрирования может быть таким простым, как «сообщения разделяются символами новой строки», но во многих случаях вам может потребоваться бинарно-безопасное кадрирование, такое как префикс длины. Например, ваш JSON может содержать символы новой строки, которые могут неправильно интерпретироваться как конец кадра.
В любом случае: с сокетами вам почти всегда необходимо читать в цикле, потому что данные могут быть разбиты на несколько пакетов, и / или размер вашего буфера приема может быть слишком мал. Поэтому обычно вы зацикливаете и буферизируете всю полезную нагрузку, пока не обнаружите EOF или конец кадра, и только после этого начнет пытаться обработать контент. В частности, обычно не следует пытаться декодировать текст, пока вы не узнаете, что у вас есть все, потому что многобайтовые символы могут охватывать несколько вызовов «чтение» / «получение», поэтому: если вы не используете декодер текста с состоянием, вы может неправильно декодировать такие символы.
Поведение, которое вы видите, будет общим практически для всех платформ и языков; это не относится к Java / C #.