QT Go TCP数据传输粘包问题

使用Go语言为服务器,QT作为客户端,利用TCP进行数据传输,当两次发送间隔过近会产生粘包现象,此时就需要一个特定的数据格式用来区分两个数据的边界,我使用 特征码(int类型用来区分是否恶意)数据包大小(int)压缩标志(bool)数据(byte),但当交互时发生问题,比如QT的自定义数据格式QBytearry会在最前面加个字段用来表示自身整体大小。下面直接列出代码:

GO:

func IntToBytes(n int) []byte {
	tmp := int32(n)
	bytesBuffer := bytes.NewBuffer([]byte{})
	binary.Write(bytesBuffer, binary.BigEndian, tmp)
	return bytesBuffer.Bytes()
}

func booltobyte(n bool) []byte {
	bytesBuffer := bytes.NewBuffer([]byte{})
	binary.Write(bytesBuffer, binary.BigEndian, n)
	return bytesBuffer.Bytes()
}

上面两个函数用于转换,将int bool 转成byte数组

其实自己写位运算也可以实现

        var buffer bytes.Buffer
	size := IntToBytes(int(9) + len(k))
	feature := IntToBytes(int(15))
	iscompress := booltobyte(false)
	data := []byte(k)
	buffer.Write(size)
	buffer.Write(feature)
	buffer.Write(iscompress)
	buffer.Write(data)
	conn.Write(buffer.Bytes())

先获取总体大小int 为4字节 bool为1字节因此首先就是4*2+1=9个字节,然后再加上数据大小最后就变为9+len(k)

再将size feature iscompress  data 发送出去即可


QT c++:

int bytetoint(QByteArray data){
    int j = data[3] & 0x000000ff;
    j |= ((data[2] << 8) & 0x0000ff00);
    j |= ((data[1] << 16) & 0x00ff0000);
    j |= ((data[0] << 24) & 0xff000000);
    return j;
}

bool bytetobool(QByteArray data){
    bool k = data[0]&0x00000001;
    return k;
}

if(receive_data.size()>(sizeof(int)+sizeof(int)))
    {
        bool isCompress;
        int data_size;
        int feature;
        QByteArray data;
        std::string k= receive_data.toStdString();
        qDebug()<<QString::fromStdString(k)<<k.size();
        data=receive_data.mid(0,4);
        data_size=bytetoint(data);
        receive_data.remove(0,4);
        data=receive_data.mid(0,4);
        feature=bytetoint(data);
        receive_data.remove(0,4);
        data=receive_data.mid(0,1);
        isCompress=bytetobool(data);
        receive_data.remove(0,1);
        qDebug()<<isCompress<<data_size<<feature;
        data=receive_data.mid(0,data_size-9);
        qDebug()<<QString(data);
        receive_data.clear();
        process_data(data);
        receive_data.remove(0,data_size);
    }

接收数据后先看看够不够前面两个数据,读取特征值与总数据包大小,看看数据包总体大小够不够,然后对其进行解析。


猜你喜欢

转载自blog.csdn.net/d7185540/article/details/80106488