Qt中処理Tcpボンド
1224 ワード
粘着パケットを処理する方法は、メッセージヘッダにメッセージの全長を加えることである.
この形式を使用します.
メッセージ全長len(4バイト)+コマンドワードcommandId(4バイト)+メッセージmsg.
アイデアは1つのbufferを用いて、メッセージがあるたびに読み終わって、それからbufferの長さを判断して、4バイトの長さlenを受け取った後、lenによってメッセージを受け取って、buffer.size()>=len、このときすでに1つの完全なパケットを受け取って処理することができて、処理が終わった後にbufferの前のlenバイトを削除して、このように繰り返します.
この形式を使用します.
メッセージ全長len(4バイト)+コマンドワードcommandId(4バイト)+メッセージmsg.
アイデアは1つのbufferを用いて、メッセージがあるたびに読み終わって、それからbufferの長さを判断して、4バイトの長さlenを受け取った後、lenによってメッセージを受け取って、buffer.size()>=len、このときすでに1つの完全なパケットを受け取って処理することができて、処理が終わった後にbufferの前のlenバイトを削除して、このように繰り返します.
//socket
connect(m_socket, SIGNAL(readyRead()), this, SLOT(ReadData()));
void Foo::ReadData()
{
m_buf->append(m_socket->readAll()); //buf QByteArray ,
int ret = 1;
while (ret > 0)
{
ret = TryDecode(*m_buf);
if (ret < 0)
qDebug() << "TryDecode() failed";
else if (ret > 0)
m_buf->remove(0, ret);
}
}
int Foo::TryDecode(QByteArray& buf)
{
if (buf.size() < 4)
return 0;
quint32 len = qFromBigEndian(*(qint32*)buf.data());
//
if (len > 1024 * 1024 * 1024)
return -1;
if (buf.size() >= len)
{
qint32 commandId = qFromBigEndian(*(qint32*)(buf.data() + 4));
qDebug() << "recv commandId: " << commandId;
if (commandId == MsgType::heartbeat)
qDebug() << "recv heartbeat";
if (commandId == MsgType::other)
{
// other
}
return len;
}
return 0;
}