Модификация размера пакета через сокеты

Я занимаюсь программированием сокетов в 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
}
}

Если данные, отправленные клиентом, получены более чем за одно чтение (даже если клиент отправил их за одну запись), мой дизайн протокола потерпит неудачу.

0

Решение

Есть ли вероятность, что сервер получит это более чем за одно чтение?

Да, 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]
    

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

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]