天天看点

QT QTcpServer 和 QTcpSocket搭建的TCP服务端,多客户端接入

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);
}
           

继续阅读