Qt|QTcpServer多个TcpSocket连接

//connection类 #ifndef CONNECTION_H #define CONNECTION_H #include #include #include #include #include #include class Connection:public QObject { Q_OBJECT public: int m_nSocketID; //-1 indicate the socket is invalid; else is the global id of the connection int m_nMsgReceived; int m_nMsgSent; QTcpSocket* m_pTcpSocket; public: Connection(){m_nSocketID = -1; } ~Connection() { if (m_pTcpSocket!=NULL) { delete m_pTcpSocket; } } public: void InitializeConnection(QTcpSocket* socket, int id) { m_pTcpSocket = socket; m_pTcpSocket->setParent(this); m_nMsgReceived = 0; m_nMsgSent = 0; m_nSocketID = id; } void DeleteConnection() { m_nSocketID = -1; m_pTcpSocket->disconnect(); // delete m_pTcpSocket; 若delete会报错, ? m_pTcpSocket = NULL; } }; #endif

//server.h #ifndef SERVER_H #define SERVER_H#include #include #include #include #include #include #include #include "ui_base.h" #include "qtheader.h" #include "Connection.h"class Server : public QMainWindow { Q_OBJECT public: Server(QWidget *parent = 0, Qt::WFlags flags = 0); ~Server(); private: Ui::BaseClass ui; public://public variables QTcpServer* m_pTcpServer; Connection* m_pConnection; QMutex m_mutexConnection; //mutex to protect the array int m_nConnected; int m_nID; public: bool InitializeServers(); void ShowStatusMessage(const QString str); public slots: void OnNewConnection(); void OnReadyRead(); void OnDisconnected(); }#endif

//server.cpp /*! @function ********************************************************************************
Function : Server Desc: constructor of the Server class, initialize the servers and variables Params: Return: Exception: -------------------------------------------------------------------------------- Notes: Examples : -------------------------------------------------------------------------------- Author:

*******************************************************************************/ Server::Server(QWidget *parent, Qt::WFlags flags) : QMainWindow(parent, flags) { ui.setupUi(this); m_nSurveillanceID = 1; m_nConnected = 0; m_pConnection = new Connection[10]; if (!InitializeServers()) { exit(-1); } }/*! @function ********************************************************************************
Function : ~Server Desc: Params: Return: Exception: -------------------------------------------------------------------------------- Notes: Examples : -------------------------------------------------------------------------------- Author:

*******************************************************************************/ Server::~Server() { //ShowMessageBox("test"); delete m_pConnection; } /*! @function ********************************************************************************
Function : InitializeServers Desc: initialize all the servers Params: Return: if any initialization of the server failed, return false Exception: -------------------------------------------------------------------------------- Notes: Examples : -------------------------------------------------------------------------------- Author:

*******************************************************************************/ bool Server::InitializeServers() { m_pTcpServer = new QTcpServer(this); if (!m_pTcpServer->listen(QHostAddress("192.168.1.100"), 8745)) { ShowMessageBox("server listen to 8745 error, exiting..."); return (false); } else { connect(m_pTcpServer, SIGNAL(newConnection()), this, SLOT(OnNewConnection())); } return true; }/*! @function ********************************************************************************
Function : OnNewConnection Desc: slot function, if there is new connection request, this function is called Params: Return: Exception: -------------------------------------------------------------------------------- Notes: Examples : -------------------------------------------------------------------------------- Author:

*******************************************************************************/ void Server::OnNewConnection() { //check how many connections established ShowStatusMessage("new connection..."); //find one connection to store the new connection int i=0; for (i=0; i<10; i++) { if (m_pConnection[i].m_nSocketID == -1) { break; } } //add new connection m_mutexConnection.lock(); (m_pConnection[i]).InitializeConnection(m_pTcpServer->nextPendingConnection(), m_nID); connect(m_pConnection[i].m_pTcpSocket, SIGNAL(readyRead()), this, SLOT(OnReadyRead())); connect(m_pConnection[i].m_pTcpSocket, SIGNAL(disconnected()), this, SLOT(OnDisconnected())); m_mutexConnection.unlock(); //set the flags m_nID++; m_nConnected++; //if the connection is 10, close the server if (m_nConnected==10) { m_pTcpServer->close(); ShowStatusMessage("Maximum connection (10) reached, new connection will be refused......"); } } /*! @function ********************************************************************************
Function : OnReadyRead Desc: slot function, if new data is available for server, this function is called Params: Return: Exception: -------------------------------------------------------------------------------- Notes: Examples : -------------------------------------------------------------------------------- Author:

*******************************************************************************/ void Server::OnReadyRead() {} /*! @function ********************************************************************************
Function : OnDisconnected Desc: slot function, if the socket is disconnected from the server this function is called Params: Return: Exception: -------------------------------------------------------------------------------- Notes: Examples : -------------------------------------------------------------------------------- Author:

*******************************************************************************/ void Server::OnDisconnected() { //get the connection that disconnected from the server QTcpSocket* socket = qobject_cast(sender()); Connection* connection = qobject_cast(socket->parent()); //delete the connection m_mutexConnection.lock(); connection->DeleteConnection(); m_mutexConnection.unlock(); ShowStatusMessage("server disconnected"); m_nSurveillanceConnected--; //if the connection is reduced from 10 to 9, reopen the server, listen if (m_nSurveillanceConnected==9) { m_pTcpServerSurveillance->listen(QHostAddress("192.168.1.100"), 8745); } } /*! @function ********************************************************************************
Function : ShowStatusMessage Desc: show the message on the status bar Params: [IN] const QString str, the message to show Return: Exception: -------------------------------------------------------------------------------- Notes: the status bar will be cleared first. Examples : -------------------------------------------------------------------------------- Author:

*******************************************************************************/ void Server::ShowStatusMessage(const QString str) { this->ui.statusBar->clearMessage(); this->ui.statusBar->showMessage(str); }

几个问题简单说明:
1.这个不见得能够直接使用,是从我完整的程序中取出的一部分,根据需要再做调整;
2.这里为什么用的值指针保存connection,而不用list,vector等:
【Qt|QTcpServer多个TcpSocket连接】首先看看继承关系:QObject->QIODevice->QAbstractSocket->QTcpSocket,对于QObject这个类来说,是不能copy的,而从其派生的类也是同样不能复制的。如果使用list或vector,会调用到类似push_back这样的函数,其本质是复制,编译会报错的。这里就采用指针来解决这个问题。


    推荐阅读