TcpServer部分:
TcpServer类继承QTcpServer。。并重载函数void incomingConnection(int socketDescriptor)。。。该函数和newConnection()信号有些类似,都是QTcpServer监听到连接时,自动触发。。。
incomingConnection函数会产生一个“描述符”-socketDescriptor,我们将socketDescriptor设置到QTcpSocket对象中(给QTcpSocket对象打上不同标记),用于区别不同的QTcpSocket对象。。。
QList<QTcpSocket*> tcpSocketConnetList;用于存放所有的QTcpSocket对象,这样就不会因为新的连接接入时将旧连接替换掉,需要注意的是当QTcpSocket断开连接时,记得删除QList<QTcpSocket*> tcpSocketConnetList中的QTcpSocket对象。。。
#ifndef TCPSERVER_H
#define TCPSERVER_H
#include <QTcpServer>
#include "tcpsocket.h"
class TcpServer : public QTcpServer
{
Q_OBJECT
public:
TcpServer();
int run();
protected:
//函数重载
void incomingConnection(int socketDescriptor);
private:
QList<QTcpSocket*> tcpSocketConnetList;
protected slots:
void Scoket_Data_Processing(QString SendData,int descriptor); //处理数据
void Socket_Disconnected(int descriptor); //断开连接处理
};
#include "tcpserver.h"
#include <QDebug>
#include <QFile>
TcpServer::TcpServer()
{
}
int TcpServer::run()
{
if (this->listen(QHostAddress::Any,3230))
{
qDebug()<<"[TcpServer]-------------------------------------------------listen sucess"<<endl;
}
else
{
qDebug()<<"[TcpServer]-------------------------------------------------listen faile"<<endl;
}
}
void TcpServer::incomingConnection(int socketDescriptor)
{
qDebug()<<"[TcpServer]------------------------------------------new Connection !!! The Num:"<< tcpSocketConnetList.count() + 1<<endl;
TcpSocket *tcpsocket = new TcpSocket();
tcpsocket->setSocketDescriptor(socketDescriptor);
tcpsocket->run();
connect(tcpsocket,SIGNAL(GetDataFromClient(QString ,int)),this,SLOT(Scoket_Data_Processing(QString,int)));
connect(tcpsocket,SIGNAL(ClientDisConnected(int)),this,SLOT(Socket_Disconnected(int)));
tcpSocketConnetList.append(tcpsocket);
//qDebug()<<"[TcpServer]-------------------------:"<<tcpSocketConnetList.count()<<endl;
//qDebug()<<"[TcpServer]-------------------------:"<<tcpSocketConnetList.size()<<endl;
}
void TcpServer::Scoket_Data_Processing(QString SendData,int descriptor)
{
for(int i = 0; i < tcpSocketConnetList.count(); i++)
{
QTcpSocket *item = tcpSocketConnetList.at(i);
if(item->socketDescriptor() == descriptor) //通过descriptor在QList中查找对应的QTcpSocket对象
{
qDebug()<<"From ---> "<< item->peerAddress().toString() <<":"<<item->peerPort();
qDebug()<<"[SendData]:"<< SendData ;
qDebug()<<"End --- "<< endl;
}
}
}
void TcpServer::Socket_Disconnected(int descriptor)
{
for(int i = 0; i < tcpSocketConnetList.count(); i++)
{
QTcpSocket *item = tcpSocketConnetList.at(i);
int temp = item->socketDescriptor();
if(-1 == temp||temp == descriptor) //测试中发现,当disconnected()信号发出,item->socketDescriptor()返回值已经为-1了,不能通过item->socketDescriptor() == descriptor来进行判断了。。。所以删除返回值为-1的QTcpSocket对象
{
tcpSocketConnetList.removeAt(i);//如果有客户端断开连接, 就将列表中的套接字删除
item->deleteLater();
qDebug()<< "[TcpSocket]---------------------------------Disconnect:" << descriptor << endl;
return;
}
}
return;
}
void TcpServer::Socket_Disconnected(int descriptor):
测试中发现,当disconnected()信号发出,item->socketDescriptor()返回值已经为-1了,不能通过item->socketDescriptor() == descriptor来进行判断了。。。所以删除返回值为-1的QTcpSocket对象
QTcpSocket部分:
#ifndef TCPSOCKET_H
#define TCPSOCKET_H
#include <QTcpSocket>
class TcpSocket : public QTcpSocket
{
Q_OBJECT
public:
TcpSocket();
void run();
private:
int Descriptor;
protected slots:
void ReceiveData_slot(); //处理readyRead信号读取数据
void ClientDisconnected_slot(); //客户端断开连接触发disconnected信号,这个槽函数用来处理这个信号
signals:
void GetDataFromClient(QString ,int); //告诉server有数据处理
void ClientDisConnected(int); //告诉server有客户端断开连接
};
#endif // TCPSOCKET_H
#include "tcpsocket.h"
TcpSocket::TcpSocket()
{
}
void TcpSocket::run()
{
Descriptor = this->socketDescriptor();
connect(this,SIGNAL(readyRead()),this,SLOT(ReceiveData_slot()));
connect(this,SIGNAL(disconnected()),this,SLOT(ClientDisconnected_slot()));
}
//TcpSocket数据接收触发
void TcpSocket::ReceiveData_slot()
{
QByteArray buffer;
buffer = readAll();
if(!buffer.isEmpty())
{
QString data = QString::fromLocal8Bit(buffer);
//数据处理
emit GetDataFromClient(data, Descriptor);
}
}
//TcpSocket断开链接触发
void TcpSocket::ClientDisconnected_slot()
{
emit ClientDisConnected(Descriptor);
}