Я занимаюсь программированием сокетов в QT, и мне нужно разработать протокол для передачи данных по TCP / IP.
Теперь мой дизайн протокола прост. Он посылает команды таким образом, что первым байтом данных, записываемых в сокет для каждой записи, будет команда. Поэтому всякий раз, когда я записываю в сокет с помощью socket-> write («CDATA») первый байт, в этом случае «C» будет означать команду для сервера что-то сделать.
Я просто хочу знать одну вещь, что будет ли запись будет разбита на несколько чтений на сервере? Я знаю, что на сервере будет размер буфера для чтения. Но можно ли получить socket-> write () на клиенте при многократном чтении на сервере, когда запись находится в пределах буфера сервера?
Чтобы прояснить этот вопрос, я приведу пример. Допустим, размер буфера чтения сокета на сервере составляет 4096 байт. Клиент записывает сокет-> запись («CDATA») на сервер. Есть ли вероятность, что сервер получит это более чем за одно чтение? Потому что у меня есть цикл while на сервере:
while{
char str[] = socket->read();
// What is the coomand in the first byte
if(str[0] == "C"){
// Do something
}
}
Если данные, отправленные клиентом, получены более чем за одно чтение (даже если клиент отправил их за одну запись), мой дизайн протокола потерпит неудачу.
Есть ли вероятность, что сервер получит это более чем за одно чтение?
Да, TCP / IP может фрагментировать сообщения любым удобным для него способом. TCP — это потоковый протокол с отслеживанием состояния: вам гарантировано, что байты, которые вы вводите на одном конце, будут выходить на другом конце в том же порядке. IP без установления соединения и на основе дейтаграмм. Из-за характера переноса TCP по IP могут возникнуть обстоятельства, при которых пакеты данных разделяются, объединяются или иным образом обрабатываются при передаче.
Вы должны найти способ дезинфицировать вашу программу в тонкостях сетевого общения. Вы можете:
Используйте протокол дейтаграмм, такой как UDP (вы теряете гарантию получения данных в том порядке, в котором они были отправлены, а также возможна потеря пакетов). Сегодняшние сети достаточно устойчивы; обычно это не проблема).
[DATAGRAM (size specified in datagram header)]
Всегда читайте блоки фиксированного размера из сети
[DATA - block of data of some fixed size]
Включите размер входящих данных в качестве заголовка, прикрепленного к передней части
[LENGTH - 4 byte integer][DATA - block of data of size LENGTH]
Используйте какой-то разделитель для указания конца данных и продолжайте чтение, пока не получите его
[DATA - indeterminately sized data][DELIMITER - end-of-data control sequence]
Скорее всего, вы можете использовать библиотечные методы, чтобы выполнить это поведение для вас, требуя очень мало кода с вашей стороны.
Других решений пока нет …