Qt中处理Tcp粘包

处理粘包的方式是在消息头部加上消息总长度。

采用该格式:

消息总长度len(4字节)+命令字commandId(4字节)+消息msg。

思路是用一个buffer,每次有消息就读完,然后判断buffer长度,收到四字节长度len后,根据len收消息,当buffer.size()>=len,这时已经收到一个完整的包就可以处理了,处理完后就将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;
}

 

你可能感兴趣的:(网络编程,Qt)