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等:

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



你可能感兴趣的:(Qt,学习研究,网络,c++)