QTcpServer多个TcpSocket连接

//connection类
#ifndef CONNECTION_H
#define CONNECTION_H
#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostAddress>
#include <QList>
#include <QMutex>

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 <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_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
********************************************************************************
<PRE>
Function : Server
Desc     : constructor of the Server class, initialize the servers and variables
Params   : 
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 : ~Server
Desc     : 
Params   : 
Return   : 
Exception: 
--------------------------------------------------------------------------------
Notes    : 
Examples : 
--------------------------------------------------------------------------------
Author   : <xxx>
</PRE>
*******************************************************************************/ 
Server::~Server()
{
	//ShowMessageBox("test");
	delete m_pConnection;
}
/*! @function
********************************************************************************
<PRE>
Function : InitializeServers
Desc     : initialize all the servers
Params   : 
Return   : 
if any initialization of the server failed, return false
Exception: 
--------------------------------------------------------------------------------
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 : OnNewConnection
Desc     : slot function, if there is new connection request, this function is called
Params   : 
Return   : 
Exception: 
--------------------------------------------------------------------------------
Notes    : 
Examples : 
--------------------------------------------------------------------------------
Author   : <xxx>
</PRE>
*******************************************************************************/ 
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
********************************************************************************
<PRE>
Function : OnReadyRead
Desc     : slot function, if new data is available for server, this function is called
Params   : 
Return   : 
Exception: 
--------------------------------------------------------------------------------
Notes    : 
Examples : 
--------------------------------------------------------------------------------
Author   : <xxx>
</PRE>
*******************************************************************************/ 
void Server::OnReadyRead()
{

}
/*! @function
********************************************************************************
<PRE>
Function : OnDisconnected
Desc     : slot function, if the socket is disconnected from the server this function is called
Params   : 
Return   : 
Exception: 
--------------------------------------------------------------------------------
Notes    : 
Examples : 
--------------------------------------------------------------------------------
Author   : <xxx>
</PRE>
*******************************************************************************/ 
void Server::OnDisconnected()
{
	//get the connection that disconnected from the server
	QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
	Connection* connection = qobject_cast<Connection*>(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
********************************************************************************
<PRE>
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   : <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这样的函数,其本质是复制,编译会报错的。这里就采用指针来解决这个问题。



你可能感兴趣的:(QTcpServer多个TcpSocket连接)