TCP основан на потоке, что означает, что вы никогда не узнаете с помощью TCP, когда сообщение начинается и заканчивается. Любое сообщение / дизайн протокола должен учитывать это.
Есть два способа определить, когда заканчивается сообщение. Первый способ - добавить разделитель в конце сообщения, а второй - включить длину в заголовок.
HTTP использует оба. Он использует пустую строку, чтобы определить, когда заканчивается заголовок. И в заголовке он получил заголовок Content-Length, который сообщает, каков размер тела.
Для двоичных протоколов я предлагаю использовать заголовок фиксированной длины, где первое целое число (4 байта) является версией, а второе целое число является длиной тела. Таким образом, вы можете легко переключать макет заголовка между версиями (поскольку версия является первым целым числом).
Для текстового протокола это действительно зависит от того, как выглядит содержимое сообщения. Проблема в том, что контент может не содержать разделитель, который будет использоваться (что может быть сложно, если вы транспортируете сообщения чата). Конечно, вы можете избежать разделителя, если он существует в реальном сообщении чата. Но, пожалуй, лучший подход - использовать макет заголовка / тела, такой как HTTP (так как его также довольно легко разобрать, и вы можете иметь количество заголовков X без необходимости менять парсер).
Сообщение будет выглядеть так:
From: Arne
To: #ChannelName
WrittenAt: 2011-07-03 12:00 GMT
Content-Length: 16
This is a text
Обратите внимание, что длина равна 16, так как новая строка была включена в тело.
Что касается общения клиент-клиент, я бы всегда проходил через сервер, если вы новичок. Это намного проще, так как в противном случае вам нужно убедиться, что хотя бы один из клиентов не находится за маршрутизатором (или будет невозможно доставить сообщение).
Просто проверьте заголовок To
, если это для чата или пользователя.