QTcpServer多个TcpSocket连接

来源:互联网 发布:linux curl 下载文件 编辑:程序博客网 时间:2024/05/17 22:19
//connection类#ifndef CONNECTION_H#define CONNECTION_H#include <QObject>#include <QTcpServer>#include <QTcpSocket>#include <QHostAddress>#include <QList>#include <QMutex>class Connection:public QObject{Q_OBJECTpublic:int m_nSocketID;//-1 indicate the socket is invalid; else is the global id of the connectionint 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 <QtGui/QMainWindow>#include <QObject>#include <QTcpServer>#include <QTcpSocket>#include <QHostAddress>#include <QList>#include <QMutex>#include "ui_base.h"#include "qtheader.h"#include "Connection.h"class Server : public QMainWindow{Q_OBJECTpublic:Server(QWidget *parent = 0, Qt::WFlags flags = 0);~Server();private:Ui::BaseClass ui;public://public variablesQTcpServer* m_pTcpServer;Connection* m_pConnection;QMutex m_mutexConnection;//mutex to protect the arrayint 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********************************************************************************<PRE>Function : ServerDesc     : constructor of the Server class, initialize the servers and variablesParams   : Return   : Exception: --------------------------------------------------------------------------------Notes    : Examples : --------------------------------------------------------------------------------Author   : <xxx></PRE>*******************************************************************************/ 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********************************************************************************<PRE>Function : ~ServerDesc     : Params   : Return   : Exception: --------------------------------------------------------------------------------Notes    : Examples : --------------------------------------------------------------------------------Author   : <xxx></PRE>*******************************************************************************/ Server::~Server(){//ShowMessageBox("test");delete m_pConnection;}/*! @function********************************************************************************<PRE>Function : InitializeServersDesc     : initialize all the serversParams   : Return   : if any initialization of the server failed, return falseException: --------------------------------------------------------------------------------Notes    : Examples : --------------------------------------------------------------------------------Author   : <xxx></PRE>*******************************************************************************/ 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********************************************************************************<PRE>Function : OnNewConnectionDesc     : slot function, if there is new connection request, this function is calledParams   : Return   : Exception: --------------------------------------------------------------------------------Notes    : Examples : --------------------------------------------------------------------------------Author   : <xxx></PRE>*******************************************************************************/ void Server::OnNewConnection(){//check how many connections establishedShowStatusMessage("new connection...");//find one connection to store the new connectionint 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 flagsm_nID++;m_nConnected++;//if the connection is 10, close the serverif (m_nConnected==10){m_pTcpServer->close();ShowStatusMessage("Maximum connection (10) reached, new connection will be refused......");}}/*! @function********************************************************************************<PRE>Function : OnReadyReadDesc     : slot function, if new data is available for server, this function is calledParams   : Return   : Exception: --------------------------------------------------------------------------------Notes    : Examples : --------------------------------------------------------------------------------Author   : <xxx></PRE>*******************************************************************************/ void Server::OnReadyRead(){}/*! @function********************************************************************************<PRE>Function : OnDisconnectedDesc     : slot function, if the socket is disconnected from the server this function is calledParams   : Return   : Exception: --------------------------------------------------------------------------------Notes    : Examples : --------------------------------------------------------------------------------Author   : <xxx></PRE>*******************************************************************************/ void Server::OnDisconnected(){//get the connection that disconnected from the serverQTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());Connection* connection = qobject_cast<Connection*>(socket->parent());//delete the connectionm_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********************************************************************************<PRE>Function : ShowStatusMessageDesc     : show the message on the status barParams   : [IN]const QString str, the message to showReturn   : Exception: --------------------------------------------------------------------------------Notes    : the status bar will be cleared first.Examples : --------------------------------------------------------------------------------Author   : <xxx></PRE>*******************************************************************************/ void Server::ShowStatusMessage(const QString str){this->ui.statusBar->clearMessage();this->ui.statusBar->showMessage(str);}

几个问题简单说明:

1.这个不见得能够直接使用,是从我完整的程序中取出的一部分,根据需要再做调整;

2.这里为什么用的值指针保存connection,而不用list,vector等:

首先看看继承关系:QObject->QIODevice->QAbstractSocket->QTcpSocket,对于QObject这个类来说,是不能copy的,而从其派生的类也是同样不能复制的。如果使用list或vector,会调用到类似push_back这样的函数,其本质是复制,编译会报错的。这里就采用指针来解决这个问题。