引用一下这位大哥的说法:
- 2016-10-25 17:511楼
-
QTcpServer使用,在我的总结里这么来好点:
1、直接继承QTcpServer(适合一端口接收多个客户端等方式),在虚函数incomeingconnection()里面写收到连接后的动作,短连接的话直接写socket收发就行,长连接的话写在Thread里面的socket收发;
2、一对一情况下,直接按照信号与槽方式继承于QObject,怎么写都可以,这种教程就多了 -
//头文件 #pragma once #include <qtcpserver.h> #include <qtcpsocket.h> #include <qmap.h> class TcpServer : public QObject { Q_OBJECT public: TcpServer(const QString &ip, int port); ~TcpServer(); private slots: void NewConnection(); void ReadAndParseData(); void SocketErr(QAbstractSocket::SocketError socketError); void SocketDisconn(); private: QTcpServer *m_tcpServer; QMap<QTcpSocket*, QString> m_socketMapData; }; // cpp文件 #include <qtcpsocket.h> #include <qthread.h> #include "TcpServer.h" #include "log.h" #include "FaceHttp.h" TcpServer::TcpServer(const QString &ip, int port) { m_tcpServer = new QTcpServer(); connect(m_tcpServer, SIGNAL(newConnection()), this, SLOT(NewConnection())); bool bsucc; if (ip.isEmpty()) { bsucc = m_tcpServer->listen(QHostAddress::AnyIPv4, port); } else { bsucc = m_tcpServer->listen(QHostAddress(ip), port); } WLog(LOG_DEBUG,"listen bsucc[%d],ip[%s] port[%d] errstr[%s]", bsucc,ip.toLocal8Bit().data(), port,m_tcpServer->errorString().toLocal8Bit().data()); } TcpServer::~TcpServer() { if (m_tcpServer != NULL) { m_tcpServer->close(); delete m_tcpServer; m_tcpServer = NULL; } } /* 连接进来的socket如果是短连接,则直接用信号槽处理即可, 如果是长连接,或者接收发送数据比较耗时,则需要分别写一个类从qtcpserver和qtcpsocket继承下来,并重载qtcpserver的incomingConnection() 函数,在incomingConnection()函数内创建继承的qtcpsocket类。 以下代码是直接信号槽处理的 */ void TcpServer::NewConnection() { // 每连进来一个,就起一个线程处理,断开连接则退出线程 if (m_tcpServer->hasPendingConnections()) // 是否有等待连接的 { QTcpSocket *socket = m_tcpServer->nextPendingConnection(); // 从列表中取出等待连接的 //socket->setParent(NULL); // 否则会提示Cannot move object with a parent //socket->setParent(NULL); // 否则会提示Cannot move object with a parent //QThread *thread = new QThread(socket); // 以socket为父类,当socket断开释放内存时也会相应的释放thread分配的内存 //socket->moveToThread(thread); //没法以此种方式移到线程,否则socket创建与使用将会在不同线程,结果将是socket并没有成功移到线程内 connect(socket, SIGNAL(disconnected()), socket, SLOT(SocketDisconn())); //connect(socket, SIGNAL(disconnected()), thread, SLOT(quit())); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(SocketErr(QAbstractSocket::SocketError))); connect(socket, SIGNAL(readyRead()), this, SLOT(ReadAndParseData())); WLog(LOG_DEBUG, "new comming,socket[%d],ip[%s] port[%d]\n", socket->socketDescriptor(), socket->peerAddress().toString().toLocal8Bit().data(), socket->peerPort()); //thread->start(); // 启动线程 } } void TcpServer::ReadAndParseData() { QTcpSocket *socket = (QTcpSocket*)sender(); QString str = m_socketMapData[socket]; //如果map中之前没有这个socket,则会以这个socket创建一个新的键值对,返回一个空QString QString recvStr = socket->readAll(); str += recvStr; // 对数据的处理 m_socketMapData[socket] = str; } void TcpServer::SocketErr(QAbstractSocket::SocketError socketError) { QTcpSocket *socket = (QTcpSocket*)sender(); WLog(LOG_ERR, "socket[%d] err[%s]", socket->socketDescriptor(), socket->errorString().toLocal8Bit().data()); } void TcpServer::SocketDisconn() { QTcpSocket* socket = (QTcpSocket*)sender(); WLog(LOG_DEBUG, "socket[%d][%s] close", socket->socketDescriptor(), socket->peerAddress().toString().toLocal8Bit().data()); if (m_socketMapData.count(socket) > 0) { m_socketMapData.remove(socket); delete socket; socket = NULL; } }
-