Qt中処理Tcpボンド


粘着パケットを処理する方法は、メッセージヘッダにメッセージの全長を加えることである.
この形式を使用します.
メッセージ全長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;
}