Qt发送端用自定义结构体发送,接收端QByteArray接收

**

Qt TCP/UDP 一端用自定义结构体发送消息,一端用QByteArray接收消息

**
用自定义结构体发送消息

void TcpServer::timeOut()
{
    QDateTime nowTime = QDateTime::currentDateTime();

    static int dhIndex = 1;
    for(int index =0;index < tcpClientSocketList.size();index++)
    {
        tcpClientSocket* perClient = tcpClientSocketList.at(index);

        if((dhIndex%2) == 1)
        {
            char data[] = "dh haha";
            char* sendData = new char[sizeof (DHPacketHeadEx)+strlen(data)];
            DHPacketHeadEx* packHead = (DHPacketHeadEx*)sendData;
            packHead->packetType = enPacketType::PACKET_BIG_CONTENT;
            packHead->len = strlen(data);
            //strcpy(packHead->pValue,data);
            memcpy(packHead->pValue,data,strlen(data));
            perClient->write(sendData,sizeof (DHPacketHeadEx)+strlen(data));//发送自定义结构体 PACKET_BIG_CONTENT包
            delete [] sendData;
        }
        else
        {
            char* sendData = new char[sizeof (DHPacketHeadEx)];
            DHPacketHeadEx* packHead = (DHPacketHeadEx*)sendData;
            packHead->packetType = enPacketType::PACKET_HEART_BEAT;
            packHead->len = 0;
            perClient->write(sendData,sizeof (DHPacketHeadEx));//发送自定义结构体 PACKET_HEART_BEAT包
            delete [] sendData;
        }

    }

    dhIndex++;

    qint64 result = lastTime.msecsTo(nowTime);
    if(result > 10000)
    {
        QString info = QString("\r\nmore than 5 Min not receive heart beat packet!");
        int len = info.length();
        emit updateServer(info,len);
        lastTime = nowTime;
    }
}

在接收端用QByteArray接收消息

void Client::slotReceiveData()
{
    while(tcpSocket->bytesAvailable() > 0)
    {
        QByteArray byteArray;
        byteArray.append(tcpSocket->readAll());//用readAll读取QByteArray到byteArray里,然后进行解析
        if(byteArray.length() >= sizeof (DHPacketHeadEx))
        {

            //DHPacketHeadEx* packetEx = (DHPacketHeadEx*)(byteArray.toStdString().c_str());//这第一种接收 获取std::string 再转c_str
            DHPacketHeadEx* packetEx = (DHPacketHeadEx*)(byteArray.data());//这第二种支持获取data 得到char*

            switch(packetEx->packetType)
            {

            case enPacketType::PACKET_HEART_BEAT:
                {
                    QString info = "收到心跳包";
                    contentListWidget->addItem(info);
                    qDebug()<<"199 收到心跳包";
                }
                break;
            case enPacketType::PACKET_CONTENT:
                {
                    char* readContent = new char[packetEx->len];
                    memcpy(readContent,(char*)packetEx->pValue,packetEx->len);

                    QString info(readContent);
                    contentListWidget->addItem(info);
                }
            case enPacketType::PACKET_BIG_CONTENT:
            {
                char* readContent = new char[packetEx->len+1];
                memcpy(readContent,(char*)packetEx->pValue,packetEx->len);

                QString info(readContent);
                contentListWidget->addItem(info);
            }

                break;
            }

             QDateTime nowTime = QDateTime::currentDateTime();
            lastReceivePacketTime = nowTime;

            continue;
        }

``

附一个实战例子
在这里插入图片描述

后面附上:
QByteArray字节数组于QTcpSocket传输之常用操作函数,标识长度与根据长度读取

向要传输的QByteArray对象的起始位置加入特定长度的字节用于表示数据长度,在接收端的第一个readAll()中读取到这个长度,并根据这个长度读取剩余的包,现把用到的函数整理如下:

1.向字节数组的起始位置拼接另一个字节数组,返回新数组

QByteArray &QByteArray::prepend(const QByteArray &ba)

2.读取字节数组起始位置len个字节,返回读取的数组

QByteArray QByteArray::left(int len) const

3.从pos位置开始的len长度的字节替换成after(如果要删除,则替换成’\0’即可)

QByteArray &QByteArray::replace(int pos, int len, const QByteArray &after)

4.返回字节数组的长度

int QByteArray::length() const

5.将字节数组转化成int

int QByteArray::toInt(bool *ok = Q_NULLPTR, int base = 10) const

QTcpSocket 发送数据的几种方法

1、QTcpSocket 继承于QAbstractSocket继承于QIODevice

2、QTcpSocket 提供的几种接收和发送数据方法

write ( const char *, qint64 ) : qint64
write ( const char * ) : qint64
write ( const QByteArray & ) : qint64
writeData ( const char *, qint64 ) : qint64
read ( char * data, qint64 maxSize ): qint64
read ( qint64 maxSize ):QByteArray
readAll ():QByteArray
readLine ( char * data, qint64 maxSize ):qint64
readLine ( qint64 maxSize = 0 ):QByteArray

3、例子1 write ( const QByteArray & ) : qint64

Cpp代码 收藏代码
//用于暂存要发送的数据
QByteArray block;
//使用数据流写入数据
QDataStream out(&block,QIODevice::ReadWrite);
//设置数据流的版本,客户端和服务器端使用的版本要相同
out.setVersion(QDataStream::Qt_4_6);

//设置发送长度初始值为0
out << (quint16) 0;
//设置发送内容
out<<hash;

//回到字节流起始位置
out.device()->seek(0);
//重置字节流长度
out << (quint16) (block.size()-sizeof(quint16));

//往套接字缓存中写入数据,并发送
tcpSocket->write(block);

3、例子2 write ( const char *, qint64 ) : qint64

Cpp代码 收藏代码
QString *a=new QString;
tcpSocket->write(a,a->length());
4、例子3 数据流直接使用QIODevice

Cpp代码 收藏代码
QDataStream in(tcpSocket);
in<< quint16(0xFFFF); //此时QIODevice加载了此数据,而且直接发送出去

quint16 length = 0;
QDataStream out(tcpSocket);//如果此时tcpSocket直接有数据发送过来
out >> length;//length获得第一个整型值,并在tcpSocket中清空该数据

附:
QTcpSocket 提供的几种接收和发送数据方法:

write ( const char *, qint64 ) : qint64
write ( const char * ) : qint64
write ( const QByteArray & ) : qint64
writeData ( const char *, qint64 ) : qint64
read ( char * data, qint64 maxSize ): qint64
read ( qint64 maxSize ):QByteArray
readAll ():QByteArray
readLine ( char * data, qint64 maxSize ):qint64
readLine ( qint64 maxSize = 0 ):QByteArray

发送数据的示例代码:
1)write ( const QByteArray & ) : qint64
//用于暂存要发送的数据
QByteArray block;
//使用数据流写入数据
QDataStream out(&block,QIODevice::ReadWrite);
//设置数据流的版本,客户端和服务器端使用的版本要相同
out.setVersion(QDataStream::Qt_DefaultCompiledVersion);

//设置发送长度初始值为0
out << (quint16) 0;
//设置发送内容
out<<"hello, mike";

//回到字节流起始位置
out.device()->seek(0);
//重置字节流长度
out << (quint16) (block.size()-sizeof(quint16));

//往套接字缓存中写入数据,并发送
tcpSocket->write(block);

2)write ( const char *, qint64 ) : qint64
QString str = “hello, mike”;
tcpSocket->write(a, a.length());

3)数据流直接使用 QIODevice
QDataStream in(tcpSocket);
in<< quint16(0xFFFF); //此时QIODevice加载了此数据,而且直接发送出去

quint16 length = 0;
QDataStream out(tcpSocket);//如果此时tcpSocket直接有数据发送过来
out >> length;//length获得第一个整型值,并在tcpSocket中清空该数据
  • 1
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值