重写<QTcpServer>、<QTcpSocket>的原因:
重写QTcpSocket的好处:可以按照自己的业务需要添加自己所需的成员
注:建立socket时,就把常用的信息缓存在socket中,省去了频繁请求数据库的操作。
注:重写<QTcpSocket>后,<QTcpServer>也就必须重写
在做中大型的项目时,使用到网络内容时,建议在原生的Qt网络基础上进行扩充,以满足具体业务的需求!
QTcpServer的扩充:
最基本的需涉及到incomingconnection函数的重写:
//此时须在继承类中实现,incomingConnection虚函数,把参数中的句柄和tcpServer进行绑定
/*
*设置套接字描述符
*/
//连接处理函数,当有新的客户端初次连接server时,自动调用该函数
void MyTcpServer::incomingConnection(qintptr handle)
{
qDebug() << "MyTcpServer::incomingConnection(qintptr handle)";
//一般不要把socket做成成员变量,因为server和socket是一对多的关系
MyTcpSocket *socket = new MyTcpSocket;
//设置套接字描述符
socket->setSocketDescriptor(handle); //内部参数就是句柄,与server建立关系
}
QTcpSocket的扩充:
将涉及到基本操作结合业务逻辑的二次实现:
简单的形如:
#ifndef MYTCPSOCKET_H
#define MYTCPSOCKET_H
/*自定义套接字类*/
#include <QObject>
#include <QTcpSocket>
#include <QByteArray>
#include <QHostAddress>
class MyTcpSocket : public QTcpSocket
{
Q_OBJECT
public:
explicit MyTcpSocket(QObject *parent = 0);
signals:
public slots:
void readSlot(); //读数据
void disconnectSlot(); //断开连接
private:
QByteArray m_data;
};
#endif // MYTCPSOCKET_H
#include "mytcpsocket.h"
#include <QDebug>
#include <QString>
MyTcpSocket::MyTcpSocket(QObject *parent) : QTcpSocket(parent)
{
//绑定信号与槽
connect(this, SIGNAL(readyRead()), this, SLOT(readSlot()));
connect(this, SIGNAL(disconnected()), this, SLOT(disconnectSlot())); //断线处理
}
void MyTcpSocket::readSlot()
{
qDebug() << "MyTcpSocket::readSlot()";
//测试代码,真正使用时,需要自己写截断函数
m_data.clear();
while(this->bytesAvailable()) //当前流内部剩余可用字节
{
m_data.append(this->readAll());
}
//json数据的拼凑/截断
//测试
qDebug() << "当前读到的数据:" << (QString)m_data;
this->write(m_data); //收到什么直接返回给client
}
/*
* 断线处理
*/
//断开连接
void MyTcpSocket::disconnectSlot()
{
//断线逻辑
//peerAddress()函数:返回QHostAddress类型,一个ip类型的数据
qDebug() << "ip addr is :" << this->peerAddress().toString() << "下线";
this->deleteLater(); //相当于delete this; 但在Qt中不建议使用,使用易造成项目崩溃
//deleteLater():操作较为温和,在需要释放时自动使用
}