这就是我在做什么:
我有一个服务器应用程序(类似于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;