QT tcpsocket 发送/接收数据

发送数据与接收数据中文乱码处理

由于有个项目需求是要求文件传输,也要求普通数据传输,而只用一个端口的情况下,如何分开对文件的处理与对数据的处理就非常重要,用官方提供的例子只有单传输文件或者单传输数据,并且传输数据对中文的支持也不是很好,所以针对项目需要,设计了一个方案,这里只列出了单发送数据模块的核心代码,很好地处理了中文传输的问题,后期整理后会慢慢补充其他模块的代码。

传输数据的结构:
待发送的数据 = 长度 + 内容
长度:用10位表示数据长度
内容:待发送的字符串

服务器端:
CTcpSocket.h

void sendDataToClient(QString _currentData);
QTcpSocket *socket; //存储客户端发过来的socket对象
QString messageBody; //消息体

CTcpSocket.cpp

//************************************
// Method:    sendDataToClient
// FullName:  CTcpSocket::sendDataToClient
// Access:    public 
// Returns:   void
// Qualifier: 发送数据到客户端,前10位表示大小
// Parameter: QString _currentData 待发送的数据流
//************************************
void CTcpSocket::sendDataToClient(QString _currentData)
{
    //获取待发送数据转码为utf8后的长度
    QString length = QString::number(_currentData.toUtf8().length());
    //构造一个10位的字符串来存储length
    QString m_len;
    m_len.fill('0', 10);
    m_len.push_back(length);
    m_len = m_len.right(10);
    //合并字符串
    _currentData = m_len + _currentData;
    //循环发送数据,每次发送1024个字节
    while (!_currentData.isEmpty())
    {
        if (_currentData.length() < 1024)
        {
            messageBody = _currentData;
            _currentData.clear();
        }
        else
        {
            messageBody = _currentData.left(1024);
            _currentData.remove(0, 1024);
        }
        QString m_message = messageBody;
        QByteArray ba = m_message.toUtf8();
        //发送数据
        socket->write(ba);
        //不缓存,直接发送
        socket->flush();
    }
    if (!socket->waitForBytesWritten())
    {
        socket->disconnectFromHost();
        socket->deleteLater();
    }
}

客户端:
NetData.h

bool m_bReceive;  //初始化位false
QByteArray m_Message; //暂存接受到的数据
int m_length;   //待接收数据的长度
QString m_resultMessage;  //接收到的数据
QTcpSocket* m_tcpsocket;

NetData.cpp

//构造函数
m_tcpsocket = new QTcpSocket();
m_tcpsocket->connectToHost(IP_ADDRESS, PORT_ADDRESS);
connect(m_tcpsocket, SIGNAL(readyRead()), this, SLOT(slot_clientReceiveData()));
//************************************
// Method:    clientReceiveData
// FullName:  NetData::clientReceiveData
// Access:    public 
// Returns:   void
// Qualifier:  接收数据
//   先读取数据的前10位表示需要接收的数据大小,然后分批接收数据
//************************************
void NetData::slot_clientReceiveData()
{
    if (!m_bReceive)
    {
        m_bReceive = true;
        //只接收前10位,数据的大小
        m_length = QString(m_tcpsocket->read(10)).toInt();
    }
    //读取数据
    m_Message += m_tcpsocket->readAll();
    int len = m_Message.length();
    //判断是否接收完毕
    if (len >= m_length)
    {
        //转换 QByteArray --> QString
        //如果不需要转换,直接在服务器端与客户端都用 QByteArray 表示即可
        m_resultMessage = QString(m_Message);
        m_tcpsocket->disconnectFromHost();
        m_tcpsocket->deleteLater();
        //发送接收的数据
        //或者根据你的需要自行处理即可
        emit signal_result(m_resultMessage);
    }
}

注:这是数据传输的核心部分,如需要源码,请在评论区留下邮箱。

你可能感兴趣的:(QT)