Дефрагментация пакетов Tcp - PullRequest
0 голосов
/ 31 мая 2019

Итак, вот что я делаю:

У меня есть серверное приложение (аналогично TcpGenericServerApp). Он принимает сообщения (подписки) и не отвечает сразу. Соединение остается открытым. Когда происходит какое-либо событие, оно отправляет уведомление всем подключенным клиентам.

Затем клиенты должны проанализировать содержимое пакета. Вот мое определение сообщения:

namespace inet;

enum PacketType
{
   SUBSCRIBE = 0;
   PUBLISH = 1;
};

// 
// Message class for event notification service based on TCP.
// 
class EventNotificationMsg extends FieldsChunk
{
    int type @enum(PacketType);
    string awesomeName;

}

Пока все довольно просто. Проблема в том, что размер пакета составляет 1000B. Этот пакет будет разделен TCP на два сегмента. Теперь я должен дефрагментировать эти пакеты, чтобы преобразовать их в EventNotificationMessage. Как я могу это сделать? Или есть более простой способ извлечь awesomeName без необходимости дефрагментировать пакеты.

Еще немного контекста:

  • Я использую TcpAppBase
  • Когда я просто пытаюсь преобразовать неполный пакет, я получаю следующую ошибку: Returning an incomplete chunk is not allowed according to the flags: 4
  • Я попытался дефрагментировать его, используя этот пример, но он выдал другую ошибку: Implicit chunk serialization is disabled to prevent unpredictable performance degradation (you may consider changing the Chunk::enableImplicitChunkSerialization flag or passing the PF_ALLOW_SERIALIZATION flag to peek). Код, который я использовал ниже.
void EventNotificationSubscriber::socketDataArrived(TcpSocket *socket, Packet *msg, bool urgent)
{

    int bytes = msg->getByteLength();
    bytesReceivedSinceReset += bytes;
    if (bytesReceivedSinceReset % expectedBytesResponse == 0) {
        // we received the last bits of a packet
        tempPacket->insertAtBack(msg->peekData());
        // the packet should be complete now
        const Ptr<const EventNotificationMsg> eventNotificationPacket = msg->peekAtFront<EventNotificationMsg>(b(-1), Chunk::PF_ALLOW_INCORRECT);
        std::string name = eventNotificationPacket->awesomeName();
        }
        // there is nothing more to do
        delete tempPacket;
        tempPacket = nullptr;
        bytesReceivedSinceReset = 0;
    } else {
        if (tempPacket == nullptr){
            tempPacket = new Packet("TempPacket");
        }
        // this is an incomplete packet
        tempPacket->insertAtBack(msg->peekData());
    }


    // do this last as this will delete the packet :O
    TcpAppBase::socketDataArrived(socket, msg, urgent);

}

Определения для переменных класса:

Packet* tempPacket;
int bytesReceivedSinceReset;
...