Qt C++ TCP服务端响应多客户端通讯

作者 : admin 本文共12041个字,预计阅读时间需要31分钟 发布时间: 2024-06-17 共1人阅读

Qt C++ TCP服务端响应多客户端通讯插图

本示例使用的设备:WIFI无线4G网络RFID云读卡器远程网络开关物流网阅读器TTS语音-淘宝网 (taobao.com)

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QMessageBox"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
bool listening=false;
QTcpServer m_server;
QTcpSocket m_socket;
//获取本机所有网卡IP------------------------------------------------------------------------------------------------------
QStringList getAllIPAddresses() {
QStringList ips;
QList list = QNetworkInterface::allAddresses();
for (int i = 0; i < list.size(); ++i) {
QHostAddress address = list.at(i);
// 检查是否为IPv4地址,并排除回环地址
if (address.protocol() == QAbstractSocket::IPv4Protocol && address != QHostAddress::LocalHost) {
ips << address.toString();
}
}
return ips;
}
//获取系统现时间-------------------------------------------------------------------------------------------------------------
QString getsystime(){
QTime time = QTime::currentTime();
QString timeStr = time.toString("hh:mm:ss.zzz");
return timeStr;
}
//获取系统日期时间-------------------------------------------------------------------------------------------------------------
QString getsysdatetime(){
QDateTime currentDateTime = QDateTime::currentDateTime();
QString dateTimeString = currentDateTime.toString("yy-MM-dd hh:mm:ss");
return dateTimeString;
}
//QByteArray转16进制QString------------------------------------------------------------------------------------------------
QString ByteArrayToHexString(QByteArray data){
QString ret(data.toHex().toUpper());
int len = ret.length()/2;
for(int i=1;ilistWidget_report->count()>30){
ui->listWidget_report->clear();
}
ui->listWidget_report->addItem(listinfo);
ui->listWidget_report->setCurrentRow(ui->listWidget_report->count()-1);
break;
case 1:
ui->listWidget_online->addItem(listinfo);
ui->listWidget_online->setCurrentRow(ui->listWidget_online->count()-1);
}
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->TEPort->setPlainText("39169");        //出厂默认39169端口
ui->spinBox_dispdelay->setValue(20);
ui->spinBox_swit->setValue(30);
ui->spinBox_voice->setValue(8);
ui->textEdit_disp->setText("欢迎您使用我们的网络读卡器!");
ui->textEdit_tts->setText("感谢您的使用,您的支持是我们最大的动力!");
QStringList ips = getAllIPAddresses();
foreach (QString ip, ips) {
ui->CBIP->addItem(ip);
}
if(ui->CBIP->count()pushButton_initserver->text()=="开启TCP服务"){
QString ipstr=ui->CBIP->currentText();
QHostAddress localeip(ipstr);
quint16 port=ui->TEPort->toPlainText().toUInt();
m_server = new QTcpServer(this);
m_server->listen(localeip, port);
connect(m_server, &QTcpServer::newConnection, this, &MainWindow::onNewConnection);
listening=true;
ui->pushButton_initserver->setText("停止");
listadditems(0,getsystime()+" Tcp Server is listening...");
}else{
listening=false;
m_server->close();
ui->pushButton_initserver->setText("开启TCP服务");
for(int i=0;iclose();
//tcpclientlist.remove(i);
ui->listWidget_online->takeItem(i);
}
tcpclientlist.clear();
listadditems(0,getsystime()+" Tcp Server is close! ");
}
}
catch(_exception)
{
listening=false;
ui->pushButton_initserver->setText("开启TCP服务");
}
}
//侦听到有新的TCP客户端接入服务--------------------------------------------------------------------------------------------
void MainWindow::onNewConnection()
{
m_socket = m_server->nextPendingConnection();
tcpclientlist.append(m_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);
connect(m_socket, &QTcpSocket::disconnected, this, &MainWindow::onClientDisconnected);
connect(m_socket, &QTcpSocket::connected, this, &MainWindow::onConnected);
//  connect(m_socket, &QTcpSocket::stateChanged, this, &MainWindow::onStateChanged);
}
//接收到TCP客户端传送来来的数据-------------------------------------------------------------------------------------------
void MainWindow::onReadyRead()
{
QByteArray buffer;
for(int row=0;rowreadAll();
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;
}
}
}
}
//侦测到TCP客户端断开连接---------------------------------------------------------------------------------------------
void MainWindow::onClientDisconnected()
{
QString RemoIp=m_socket->peerAddress().toString();
quint16 RemoPort= m_socket->peerPort();
for(int i=0;ipeerAddress().toString()==RemoIp && tcpclientlist.at(i)->peerPort()==RemoPort){
tcpclientlist.remove(i);
ui->listWidget_online->takeItem(i);
listadditems(0,getsystime()+" Disconn: "+RemoIp+":"+QString::number(RemoPort));
}
}
}
void MainWindow::onConnected()
{
QString RemoIp=m_socket->peerAddress().toString();
QString RemoPort=QString::number( m_socket->peerPort());
}
//void MainWindow::onStateChanged(QAbstractsocket::SocketState socketstate){
//    switch (socketstate){
//    case QAbstractSocket::UnconnectedState:ui->labConnectState->setText("Unconnectedstate");break;
//    case QAbstractSocket::HostLookupState:ui->labConnectState->setText("HostLookupstate");break;
//    case QAbstractSocket::ConnectedState:ui->labConnectState->setText("connectedstate");break;
//    case QAbstractSocket::ConnectingState:ui->labConnectState->setText("connectingstate");break;
//    case QAbstractSocket::BoundState: ui->labConnectState->setText("Boundstate");break;
//    case QAbstractSocket::ClosingState:ui->labConnectState->setText("closingstate");break;
//    case QAbstractSocket::ListeningState:ui->labConnectState->setText("listeningstate");break;
//    }
//}
//解析读取IC卡卡号-------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_c1_cf(int socketid,unsigned char databuff[], qint64 buflen)
{
QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应
QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256);   //设备自编机号
QString FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256);    //数据包号
int cardnolen=databuff[9];
QString CardnoHexZ="";          //16进制卡号正码
QString CardnoHexF="";          //16进制卡号反码
for (int i=0;i<cardnolen;i++){
CardnoHexZ=CardnoHexZ+QString::asprintf("%02X", databuff[10+i]);
if(i<4){CardnoHexF=CardnoHexF+QString::asprintf("%02X", databuff[9+cardnolen-i]);}   //只取4个字节计算8H10D反码
}
QString SerialNumber="";        //设备全球唯一硬件序号
for (int i=10+cardnolen;iplainTextEdit_msg->setPlainText(DispInf);
if(ui->checkBox_Resp->isChecked()){Respondinfo(socketid,getsysdatetime()+"卡号:"+Cardno8H10D);}  //回应驱动设备显示+蜂鸣响声
}
//解析读取ID卡卡号-------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_d1_df(int socketid,unsigned char databuff[], qint64 buflen)
{
QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应
QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256);   //设备自编机号
QString FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256);    //数据包号
QString CardnoHexZ="";          //16进制卡号正码
QString CardnoHexF="";          //16进制卡号反码
for (int i=0;i<5;i++){
CardnoHexZ=CardnoHexZ+QString::asprintf("%02X", databuff[9+i]);
if(i<4){CardnoHexF=CardnoHexF+QString::asprintf("%02X", databuff[9+3-i]);}   //只取4个字节计算8H10D反码
}
QString SerialNumber="";        //设备全球唯一硬件序号
for (int i=9+5;iplainTextEdit_msg->setPlainText(DispInf);
if(ui->checkBox_Resp->isChecked()){Respondinfo(socketid,getsysdatetime()+"卡号:"+Cardno8H10D);}  //回应驱动设备显示+蜂鸣响声
}
void MainWindow::on_btnClose_clicked()
{
m_server->close();
}
//向指定的客户端发送数据--------------------------------------------------------------------------------------------------------------
void MainWindow::SendBufToSockID(int socketid,QByteArray rbuffer){
m_socket=tcpclientlist.at(socketid);
m_socket->write(rbuffer);
QString RemoIp=m_socket->peerAddress().toString();
QString RemoPort=QString::number( m_socket->peerPort());
QString SendHex=getsystime()+" Send To: "+(RemoIp+":"+RemoPort+"             ").mid(0,22);
SendHex=SendHex+ByteArrayToHexString(rbuffer);
listadditems(0,SendHex);
}
void MainWindow::on_pushButton_initserver_clicked()
{
initserver();
}
//驱动读卡器蜂鸣响声-----------------------------------------------------------------------
void MainWindow::on_btnSendbeep_clicked()
{
QListWidgetItem *item = ui->listWidget_online->currentItem();
int row = ui->listWidget_online->row(item);
if(rowCBbeep->currentIndex());       //蜂鸣响声代码
SendBufToSockID(row,sendData);
}
}
//驱动读卡器开启继电器-----------------------------------------------------------------------
void MainWindow::on_btnswitchon_clicked()
{
QListWidgetItem *item = ui->listWidget_online->currentItem();
int row = ui->listWidget_online->row(item);
if(rowCBSwitch->currentIndex());
bool status;
sendData.append(swithno.toUInt(&status,16));       //选择继电器
quint16 deltime=ui->spinBox_swit->value();
sendData.append(deltime % 256);                    //开启延时低位
sendData.append(deltime / 256);                    //开启延时高位
SendBufToSockID(row,sendData);
}
}
//驱动读卡器关闭已开启的继电器-----------------------------------------------------------------
void MainWindow::on_btnswitchoff_clicked()
{
QListWidgetItem *item = ui->listWidget_online->currentItem();
int row = ui->listWidget_online->row(item);
if(rowCBSwitch->currentIndex());
bool status;
sendData.append(swithno.toUInt(&status,16));       //选择继电器
quint16 deltime=ui->spinBox_swit->value();
sendData.append(deltime % 256);                    //开启延时低位
sendData.append(deltime / 256);                    //开启延时高位
SendBufToSockID(row,sendData);
}
}
//驱动读卡器蜂鸣响声并显示文字---------------------------------------------------------------------
void MainWindow::on_btnDispbeep_clicked()
{
QListWidgetItem *item = ui->listWidget_online->currentItem();
int row = ui->listWidget_online->row(item);
if(rowCBbeep->currentIndex());       //蜂鸣响声代码,255表示不响声
sendData.append(ui->spinBox_dispdelay->value());   //文字显示时长,
QString dispstr=ui->textEdit_disp->toPlainText()+"                                  ";  //加空格是为了确保满屏34位显示
QByteArray Dispbyte=dispstr.toLocal8Bit();
for(int i=0;ilistWidget_online->currentItem();
int row = ui->listWidget_online->row(item);
if(rowspinBox_voice->value()>16){ui->spinBox_voice->setValue(16);} //tts最大语音取值16
QString strls="[v"+QString::asprintf("%d",ui->spinBox_voice->value())+"]";
strls=strls+ui->textEdit_tts->toPlainText().trimmed();
QByteArray SpeakArr=strls.toLocal8Bit();         //TS语音转换为Ansi码
quint8 speakbytes=SpeakArr.size();
quint8 dispbytes=34;                //双行显示屏显示长度34,四行屏显示长度72
QByteArray sendData;
sendData.append(0x5c);                             //功能码
quint16 devno=0;
sendData.append(devno % 256);                      //机号低位
sendData.append(devno / 256);                      //机号高位,高低位都为0表示所有机
sendData.append(ui->CBbeep->currentIndex());       //蜂鸣响声代码,取值255表示不响
QString swithno="F"+QString::asprintf("%d",ui->CBSwitch->currentIndex());
bool status;
sendData.append(swithno.toUInt(&status,16));       //选择继电器
quint16 deltime=ui->spinBox_swit->value();
sendData.append(deltime % 256);                    //延时低位
sendData.append(deltime / 256);                    //延时高位
sendData.append(ui->spinBox_dispdelay->value());   //文字显示时长,
quint8 begindisp =0;                               //在显示屏中的哪个位置开始显示,一般取0
sendData.append(begindisp);
sendData.append(dispbytes);                        //显示文字长度
sendData.append(speakbytes);                       //tts语音长茺
QString dispstr=ui->textEdit_disp->toPlainText()+"                                  ";  //加空格是为了确保满屏34位显示
QByteArray Dispbyte=dispstr.toLocal8Bit();
for(int i=0;i<dispbytes;i++){
sendData.append(Dispbyte[i]);       //显示信息
}
for(int i=0;iCBbeep->currentIndex());       //蜂鸣响声代码,255表示不响声
RespBuff.append(ui->spinBox_dispdelay->value());   //文字显示时长,
QString dispstr=Dispinf+"                                  ";  //加空格是为了确保满屏34位显示
QByteArray Dispbyte=dispstr.toLocal8Bit();
for(int i=0;iwrite(RespBuff);
QString RemoIp=m_socket->peerAddress().toString();
QString RemoPort=QString::number( m_socket->peerPort());
QString SendHex=getsystime()+" Send To: "+(RemoIp+":"+RemoPort+"             ").mid(0,22);
SendHex=SendHex+ByteArrayToHexString(RespBuff);
listadditems(0,SendHex);
}
void MainWindow::on_btncopyreport_clicked()
{
QString listinf;
int row=ui->listWidget_report->count();
if (row<1){
return;
}else{
for (int i=0;ilistWidget_report->item(i);
listinf=listinf+item->text()+"
";
}
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(listinf);
QMessageBox::information(this, "提示", "显示数据报文已拷贝到剪切板");
}
}

源码下载 :https://download.csdn.net/download/zhangjin7422/89421064

本站无任何商业行为
个人在线分享 » Qt C++ TCP服务端响应多客户端通讯
E-->