qt+Tcp服务端+线程,支持多个客户端连接

头文件:

#ifndef MYTCPCLASS_H
#define MYTCPCLASS_H

#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QMessageBox>
#include <QTimer>
#define MAX_SOCKETBUF 10000
class MyTcpClass : public QObject
{
    Q_OBJECT
public:
    MyTcpClass();
    ~MyTcpClass();
    void initMyTcp();
    void SendData();
    void RecvData();
private:
    QTimer *myTimer;
    QTcpServer *myTcpSocket;
    QList<QTcpSocket*> TcpConnect;

    QHostAddress TargetAddress;
    quint16 TargetComPort;
signals:

public slots:
    void slot_CloseThread();
    void slot_StartThread();
    void slot_TimerOut();
    void slot_NewConnection();
    void slot_DisConnection();
};

#endif // MYTCPCLASS_H

实现:

#include "MyTcpClass.h"

MyTcpClass::MyTcpClass()
{
    TargetAddress = QHostAddress("");
    TargetComPort = 0;
}

MyTcpClass::~MyTcpClass()
{
    if(myTcpSocket != nullptr)
    {
        delete  myTcpSocket;
        myTcpSocket = nullptr;
    }
}

void MyTcpClass::initMyTcp()
{
    myTcpSocket = new QTcpServer();//服务器端监听套接字

    //监听任意地址尝试连接
    if(!myTcpSocket->listen(QHostAddress::Any,14521))
    {
        qDebug()<<"监听失败:"<<myTcpSocket->errorString();
        QMessageBox msg;
        msg.setText("Listen failed!");
        msg.setWindowFlags(Qt::WindowStaysOnTopHint);
        msg.exec();
        myTcpSocket->close();
        return;
    }
    else
    {
        qDebug()<<"监听成功";
        connect(myTcpSocket,&QTcpServer::newConnection,this,&MyTcpClass::slot_NewConnection);
    }
}

void MyTcpClass::slot_StartThread()
{
    initMyTcp();
    myTimer = new QTimer();
    connect(myTimer,&QTimer::timeout,this,&MyTcpClass::slot_TimerOut);
    myTimer->start(50);
}

void MyTcpClass::slot_TimerOut()
{
    RecvData();
    SendData();
}
void MyTcpClass::SendData()
{
    char data[1024] = "fhewfhefwafaefew";
    for(int i=0;i<TcpConnect.size();i++)
    {
        if(TcpConnect[i]->isWritable())
            TcpConnect[i]->write(data,sizeof(data));
    }
}

void MyTcpClass::RecvData()
{
    for(int i=0;i<TcpConnect.size();i++)
    {
        char RecDataBuf[MAX_SOCKETBUF];//unsigned
        while(!TcpConnect[i]->atEnd())
        {
           qint64 ctrecnum = TcpConnect[i]->read(RecDataBuf, MAX_SOCKETBUF);

           if(ctrecnum < 4)
                break;

           qDebug()<<"num= "<< TcpConnect[i]->peerAddress().toString()<<  " size= "<<ctrecnum;
            //进行处理的一些操作
            if(ctrecnum > 4)		//至少大于包头长度
            {
//                if(!pMyDataManage->MyBuff.isFull())
//                    pMyDataManage->MyBuff.write(RecDataBuf, ctrecnum);
            }
        }
     }
}
void MyTcpClass::slot_CloseThread()
{
    myTimer->stop();;
    delete myTimer;

    int i=0;
    foreach(QTcpSocket* soc, TcpConnect)
    {
        //qDebug()<<soc->peerAddress().toString()<<"  closed"<<endl;
        soc->deleteLater();
        TcpConnect.removeAt(i); //tcpSockets.removeOne(soc);
        i++;
    }

    myTcpSocket->close();
    if(myTcpSocket != nullptr)
    {
        delete myTcpSocket;
        myTcpSocket = nullptr;
    }
}
void MyTcpClass::slot_NewConnection()
{
    qDebug()<<"success  ";
    TcpConnect.append(myTcpSocket->nextPendingConnection());//返回已连接套接字对象
    TcpConnect[TcpConnect.size()-1]->setProperty("port",TcpConnect[TcpConnect.size()-1]->peerPort());
    connect(TcpConnect[TcpConnect.size()-1],&QTcpSocket::disconnected,this,&MyTcpClass::slot_DisConnection);
}

void MyTcpClass::slot_DisConnection()
{
    //qDebug()<<"delete  before= "<<TcpConnect.size();
    int i=0;
    foreach(QTcpSocket* soc, TcpConnect)
    {
        if(soc->state() == QTcpSocket::UnconnectedState)
        {
            //qDebug()<<soc->peerAddress().toString()<<"  closed"<<endl;
            soc->deleteLater();
            TcpConnect.removeAt(i); //tcpSockets.removeOne(soc);
        }
        i++;
    }
    //qDebug()<<"delete  late= "<<TcpConnect.size();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值