消费机 水控机 售饭机 电梯门禁 门禁机
快速寻找产品(请输入产品型号或名称的关键词):
首页> 技术文档

技术文档

C++支持多个客户端同时连接的TCP服务端

发布者:广州荣士电子有限公司         发布时间: 2024-6-12 

#include "mainwindow.h"

#include "ui_mainwindow.h"
#include "QMessageBox"
#include <QDebug>
#include <exception>
#include <QTcpServer>
#include <QTcpSocket>
#include <QObject>
#include <QTime>
#include <QTreeWidgetItem>
#include <QClipboard>
  

//启动、关闭TCP服务-------------------------------------------------------------------------------------------------------
void MainWindow::initserver(){
    try{
        if(ui->pushButton_initserver->text()=="开启TCP服务"){
            QString ipstr=ui->CBIP->currentText();     //TCP服务侦听的本机IP
            QHostAddress localeip(ipstr);                    //TCP服务侦听的端口
            quint16 port=ui->TEPort->toPlainText().toUInt();
 
            m_server = new QTcpServer(this);  
            m_server->listen(localeip, port);     //开启TCP 侦听服务
            connect(m_server, &QTcpServer::newConnection, this, &MainWindow::onNewConnection);  //给TCP服务绑定 侦测新客户端接入的槽函数
 
            ui->pushButton_initserver->setText("停止");
            listadditems(0,getsystime()+" Tcp Server is listening...");
        }else{
            m_server->close();    //停止TCP服务
            ui->pushButton_initserver->setText("开启TCP服务");
            for(int i=0;i<tcpclientlist.count();i++){   //关闭并删除所有客户端socket
                tcpclientlist.at(i)->close();
                ui->listWidget_online->takeItem(i);
            }
            tcpclientlist.clear();
            listadditems(0,getsystime()+" Tcp Server is close! ");
        }
    }
    catch(_exception)
    {
        ui->pushButton_initserver->setText("开启TCP服务");
    }
}

//侦听到有新的TCP客户端接入服务--------------------------------------------------------------------------------------------
void MainWindow::onNewConnection()
{
    m_socket = m_server->nextPendingConnection();    //侦测到新TCP客户端接入的socket套接字
    tcpclientlist.append(m_socket);                               //将socket套接字存入在线客户端列表
 
    QString RemoIp=m_socket->peerAddress().toString();
    QString RemoPort=QString::number( m_socket->peerPort());
    listadditems(1,RemoIp+":"+RemoPort);
    listadditems(0,getsystime()+" NewConn "+RemoIp+":"+RemoPort);
 
    connect(m_socket, &QTcpSocket::readyRead, this, &MainWindow::onReadyRead);   //为socket绑定接收数据的槽函数
    connect(m_socket, &QTcpSocket::disconnected, this, &MainWindow::onClientDisconnected);  //为socket绑定侦测客户端断开连接的槽函数
    connect(m_socket, &QTcpSocket::connected, this, &MainWindow::onConnected);  //为socket绑定在线的槽函数
}


//侦测到TCP客户端断开连接---------------------------------------------------------------------------------------------
void MainWindow::onClientDisconnected()
{
    QString RemoIp=m_socket->peerAddress().toString();
    quint16 RemoPort= m_socket->peerPort();
    for(int i=0;i<tcpclientlist.count();i++){
        if(tcpclientlist.at(i)->peerAddress().toString()==RemoIp && tcpclientlist.at(i)->peerPort()==RemoPort){
            tcpclientlist.remove(i);
            ui->listWidget_online->takeItem(i);   //在线列表删除已断开的客户端socket
            listadditems(0,getsystime()+" Disconn: "+RemoIp+":"+QString::number(RemoPort));
        }
    }
}

//接收到TCP客户端传送来来的数据-------------------------------------------------------------------------------------------
void MainWindow::onReadyRead()
{
    QByteArray buffer;
    for(int row=0;row<tcpclientlist.count();row++){   //接收到数据后,查询在线列表判断是哪个socket过来的数据
        m_socket=tcpclientlist.at(row);
        buffer = m_socket->readAll();
        if(buffer.length()!=0){    
            QString RemoIp=m_socket->peerAddress().toString();
            QString RemoPort=QString::number( m_socket->peerPort());
            listadditems(0,getsystime()+" Receive: "+RemoIp+":"+RemoPort+"    "+ByteArrayToHexString(buffer));
 
            unsigned char databuff[buffer.length()];
            std::copy(buffer.begin(), buffer.end(), databuff);
 
            switch (databuff[0]){
            case 0xc1:
            case 0xcf:
                 Analyze_c1_cf(row,databuff,buffer.length());          //解析读取IC卡卡号
                 break;
 
            case 0xd1:
            case 0xdf:
                 Analyze_d1_df(row,databuff,buffer.length());          //解析读取ID卡卡号
                 break;
 
            default:
                break;
            }
        }
    }
}
 

//服务器向指定的客户端发送指令-------------------------------------------------------------------------------------------
void MainWindow::Respondinfo(int socketid,QString Dispinf)
{
    QByteArray RespBuff;
    RespBuff.append(0x5A);                                         //功能码
    quint16 devno=0;
    RespBuff.append(devno % 256);                             //机号低位
    RespBuff.append(devno / 256);                               //机号高位,高低位都为0表示任意机
    RespBuff.append(ui->CBbeep->currentIndex());       //蜂鸣响声代码,255表示不响声
    RespBuff.append(ui->spinBox_dispdelay->value());   //文字显示时长,
    QString dispstr=Dispinf+"                                  ";  //显示文字,加空格是为了确保满屏34位显示
    QByteArray Dispbyte=dispstr.toLocal8Bit();              //将显示文字加入发送缓冲
    for(int i=0;i<34;i++){
        RespBuff.append(Dispbyte[i]);
    }
 
    m_socket=tcpclientlist.at(socketid);                        //向指定的客户端socket发数据
    m_socket->write(RespBuff);
}


 

 
上一篇:Web Serial Api 浏览器打开串口发送指令读写IC卡 下一篇:RFID卡ST25DV04K/16K/64K读写指令
     
Guangzhou Rong Shi Electronics Co., Ltd., China 广州荣士电子有限公司 备案/许可证编号:粤ICP备11063836号
TEL  020-22307058    020-82301718
消费机
隐私政策

消费机 水控机 售饭机 电梯门禁 门禁机

网站地图 xml