關于message
訊息分片
訊息分片的發送
訊息分片允許將多個訊息封裝成一條訊息,在發送自定義協議資料時,我們經常需要在訊息前“填充”一個包頭,如下代碼,在發送的時候加上 zmq::send_flags::sndmore 標識(對應 zeromq ZMQ_SNDMORE),表示后面還有訊息,這樣 zeromq 會將 ZMQ_SNDMORE 的訊息和最后一段訊息拼裝成一條完整的訊息發送,
int SendData(char* pMsg, int iMsgLen)
{
tagMsgHead stHead;
bzero(&stHead, sizeof(stHead));
...
stHead.Len = iMsgLen;
stHead.Crc = 0;
try
{
m_socket.send(zmq::const_buffer((const void*)(&stHead), sizeof(stHead)),zmq::send_flags::dontwait|zmq::send_flags::sndmore);
m_socket.send(zmq::const_buffer((const void*)(pMsg), static_cast<size_t>(iMsgLen)), zmq::send_flags::dontwait);
}
catch (...)
{
....
}
return 0;
}
訊息分片的接收
需要注意的是,如果發送使用了 ZMQ_SNDMORE 分片,那么在接收時也需要分多次 recv 接收資料(這點比較麻煩),開始的時候以為 recv 接收的是一個完成的包,后面才知道 recv 接收的其實是“幀”資料,多個“幀”拼裝成一個訊息,具體接收方法如下:
Buffer buffer;
while (1) {
// 接收訊息
zmq_msg_t identify;
zmq_msg_t message;
zmq_msg_init(&identify);
zmq_msg_init(&message);
zmq_recvmsg(socket, &identify, 0);
zmq_recvmsg(socket, &message, 0);
buffer.Append(zmq_msg_data(&message), zmq_msg_size(&message));
// 檢查是否還有更多訊息可讀
while(zmq_msg_more(&message)) {
zmq_recvmsg(socket, &message, 0);
buffer.Append(zmq_msg_data(&message), zmq_msg_size(&message));
}
zmq_msg_close(&identify);
zmq_msg_close(&message);
}
使用 cppzmq 的話,代碼如下:
Buffer buffer;
while (1) {
// 接收訊息
zmq::message_t identity;
zmq::message_t message;
socket.recv(identity, zmq::recv_flags::none);
socket.recv(message, zmq::recv_flags::none);
buffer.Append(message.data(), message.size());
// 檢查是否還有更多訊息可讀
while(message.more()) {
socket.recv(message, zmq::recv_flags::none);
buffer.Append(message.data(), message.size());
}
}
使用 ZMQ_SNDMORE 后接收也需要分片接收,這個確實是比較麻煩的地方,個人覺得如果改成一次接識訓更好,因為這樣更符合使用的“直覺”,
后面會不斷更新這部分,有新的問題會加進來,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/547435.html
標籤:C++
