QT5实现高效TCP服务器与客户端通信

📅 2026/7/10 14:01:49
QT5实现高效TCP服务器与客户端通信
服务器端#include widget.h #include ui_widget.h Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui-setupUi(this); //准备组件初始化组件状态 this-setFixedSize(800,600); chatwidget new QListWidget(this); chatwidget-setFixedSize(800,430); chatwidget-setEnabled(false); portedit new QLineEdit(this); portedit-resize(400,50); portedit-move(80,480); startbtn new QPushButton(启动,this); startbtn-setStyleSheet(background-color:red); startbtn-resize(150,80); startbtn-move(520,465); //startbtn按钮的点击信号与槽函数连接 connect(startbtn,QPushButton::clicked,this,Widget::startbtn_slot); ser new QTcpServer(this);//实意化服务器类对象 connect(ser,QTcpServer::newConnection,this,Widget::serconnect_slot); //连接 每当新的客户端连接服务器发出的newconection信号 与对应的槽函数 } Widget::~Widget() { delete ui; } //startbtn按钮的点击信号对应的槽函数 void Widget::startbtn_slot() { if(startbtn-text() 启动) { //启动按钮后调用监听 int port portedit-text().toUInt();//获取行编辑器输入的端口号 if(port1024 || port49151) { QMessageBox::information(this,提示,端口号不可用); return; } if(ser-listen(QHostAddress::Any,port)true)//设置服务器的IP地址端口号,监听状态 { //启用聊天窗口禁用端口行编辑器,设置按钮背景色 chatwidget-setEnabled(true); portedit-setEnabled(false); startbtn-setStyleSheet(background-color:blue); QMessageBox::information(this,成功,服务器启动成功); startbtn-setText(关闭);//启动后将按钮文本设置为关闭 } else { QMessageBox::information(this,失败,服务器启动失败); } } else if(startbtn-text() 关闭) { chatwidget-setEnabled(false); portedit-setEnabled(true); startbtn-setStyleSheet(background-color:red); QMessageBox::information(this,成功,服务器关闭); startbtn-setText(开启);//启动后将按钮文本设置为开启 } } //服务器发出的newconection信号对应的槽函数处理 void Widget::serconnect_slot() { QTcpSocket *socket ser-nextPendingConnection();//返回连接到的客户端信息 clilist.append(socket);//将信息放到容器中保存 //每当有客户端向服务器发送数据时socket会向服务器发送一个readyread信号 connect(socket,QTcpSocket::readyRead,this,Widget::socket_readyread);//将所连接客户端的服务器都连接到槽函数 } //处理socket发送的readyread信号的槽函数 void Widget::socket_readyread() { //在这个函数内就可以实现数据收发 //先遍历链表中的客户端如果是无效链接则删除掉 for(int i0;iclilist.length();i) { //判断连接状态 if(clilist[i]-state() QTcpSocket::UnconnectedState) //判断这个链接状态是否是无效链接 { //是则删除 clilist.removeAt(i); } //不是无效链接判断是否有数据待读 else if(clilist[i]-bytesAvailable() ! 0) { QByteArray msg clilist[i]-readAll();//将客户端发来的数据督导msg里面 chatwidget-addItem(QString::fromLocal8Bit(msg));//将信息展示在聊天框上 //遍历转发除了发送信息客户端 for(int j0;jclilist.length();j) { if(i!j) { clilist[j]-write(msg); } } } } }客户端#include widget.h #include ui_widget.h Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui-setupUi(this); this-setFixedSize(800,600); chatwidget new QListWidget(this); chatwidget-resize(800,400); chatwidget-setEnabled(false); usrlab new QLabel(用户名,this); usrlab-move(30,470); usredit new QLineEdit(this); usredit-move(90,460); usredit-resize(300,30); iplab new QLabel(ip,this); iplab-move(30,510); ipedit new QLineEdit(this); ipedit-move(90,500); ipedit-resize(300,30); portlab new QLabel(port,this); portlab-move(30,545); portedit new QLineEdit(this); portedit-move(90,540); portedit-resize(300,30); msgedit new QLineEdit(this); msgedit-move(90,410); msgedit-resize(400,40); msgedit-setEnabled(false); sendbtn new QPushButton(发送,this); sendbtn-move(510,408); sendbtn-resize(150,47); // sendbtn-setStyleSheet(background-color:red); sendbtn-setEnabled(false); connectbtn new QPushButton(连接服务器,this); connectbtn-move(480,490); connectbtn-resize(200,80); connectbtn-setStyleSheet(background-color:red); cli new QTcpSocket(this);//实意化客户端类对象 //点击连接服务器按钮的信号与槽函数连接 connect(connectbtn,QPushButton::clicked,Widget::connectbtn_slot); connect(sendbtn,QPushButton::clicked,Widget::sendbtn_slot); //客户端连接信号与槽函数连接 connect(cli,QTcpSocket::connected,this,Widget::connected_slot); connect(msgedit,QLineEdit::textChanged,this,Widget::sentbtn_available_slot); } void Widget::connected_slot() { QMessageBox::information(this,连接,连接服务器成功); } void Widget::connectbtn_slot() { //一按钮两用 if(connectbtn-text()连接服务器) { //点击连接服务器之后获取行编辑器的文本信息 QString usrnameusredit-text(); quint16 portportedit-text().toUInt(); QString ipipedit-text(); //连接整个后禁用服务器端信息编辑启用聊天窗口和信息编辑器 chatwidget-setEnabled(true); msgedit-setEnabled(true); usredit-setEnabled(false); ipedit-setEnabled(false); portedit-setEnabled(false); //向给定的IP地址端口号发送链接请求 cli-connectToHost(ip,port); connectbtn-setText(断开服务器); //连接成功后会发送cli会发送一个connected信号对这个信号处理即可 } else { //断开连接整个后启用服务器端信息编辑禁用聊天窗口和信息编辑器 usredit-setEnabled(true); ipedit-setEnabled(true); portedit-setEnabled(true); chatwidget-setEnabled(false); sendbtn-setEnabled(false); msgedit-setEnabled(false); QString msg usrname 离开聊天室 ; cli-write(msg.toLocal8Bit()); cli-disconnectFromHost(); connectbtn-setText(连接服务器); } } void Widget::sendbtn_slot() { QString msg usrname : msgedit-text(); cli-write(msg.toLocal8Bit()); QString msg1msgedit-text(); QListWidgetItem *Itemnew QListWidgetItem(msg1); Item-setTextAlignment(Qt::AlignRight); //自己发送的文本右边显示 chatwidget-addItem(Item); msgedit-clear(); } //处理readyread对应槽函数 void Widget::readyRead_slot() { QByteArray msg cli-readAll(); chatwidget-addItem(QString::fromLocal8Bit(msg)); } void Widget::disconnect_slot() { QMessageBox::information(this,断开,断开服务器连接成功); } void Widget::sentbtn_available_slot() { if(msgedit-text().length()0) { sendbtn-setEnabled(true); } } Widget::~Widget() { delete ui; }学生管理系统#include widget.h #include ui_widget.h Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui-setupUi(this); if(!db.contains(mydb.db)) { db QSqlDatabase::addDatabase(QSQLITE); db.setDatabaseName(mydb.db); } if(!db.open()) { QMessageBox::information(this,失败,数据库打开失败); return; } QString sql create table if not exists Stu(numb int ,name char,sex char,score float);; QSqlQuery query; if(query.exec(sql)false) { QMessageBox::information(this,提示,创建数据表失败); return; } } Widget::~Widget() { delete ui; } void Widget::on_addbtn_clicked() { ui-tableWidget-clear(); //QString sql QString(%1) int ui_numbui-numbedit-text().toUInt(); QString ui_name ui-nameedit-text(); QString ui_sex ui-sexedit-text(); float ui_score ui-scoreedit-text().toFloat(); if(ui_sexNULL || ui_numb0 || ui_score0 || ui_nameNULL) { QMessageBox::information(this,提示,请将信息填写完整); return; } else if(!(ui_sex 男 || ui_sex 女)) { QMessageBox::information(this,提示,性别信息错误); return; } QString sql QString(insert into Stu values(%1,%2,%3,%4);).arg(ui_numb).arg(ui_name).arg(ui_sex).arg(ui_score); QSqlQuery query; if(query.exec(sql)) { QMessageBox::information(this,提示,添加数据成功); ui-numbedit-clear(); ui-nameedit-clear(); ui-sexedit-clear(); ui-scoreedit-clear(); return; } else { QMessageBox::information(this,提示,添加数据失败); return; } } void Widget::on_searchbtn_clicked() { ui-tableWidget-clear(); QString sql; if(ui-numbedit-text()NULL) { sql select * from Stu; } else { sql QString(select * from stu where numb%1;).arg(ui-numbedit-text()); } QSqlQuery query; if(!query.exec(sql)) { QMessageBox::information(this,提示,查询失败); return; } int i0; while(query.next()) { //任意一个查询的结果 //qDebug() query.record().value(1).toString(); for(int j0;jquery.record().count();j) { qDebug() query.record().value(j).toString(); QTableWidgetItem *Itemnew QTableWidgetItem(query.record().value(j).toString()); Item-setTextAlignment(Qt::AlignCenter); ui-tableWidget-setItem(i,j,Item); } i; } } void Widget::on_updatabtn_clicked() { ui-tableWidget-clear(); int ui_numbui-numbedit-text().toUInt(); QString ui_name ui-nameedit-text(); QString ui_sex ui-sexedit-text(); float ui_score ui-scoreedit-text().toFloat(); if(ui_sexNULL || ui_numb0 || ui_score0 || ui_nameNULL) { QMessageBox::information(this,提示,请将信息填写完整); return; } else if(!(ui_sex 男 || ui_sex 女)) { QMessageBox::information(this,提示,性别信息错误); return; } //QString sql QString(update Stu set numb%1 where name%2).arg(ui_numb).arg(ui_name); //qDebug() sql; QString sql QString(update Stu set name%1,sex%2,score%3 where numb%4;).arg(ui_name).arg(ui_sex).arg(ui_score).arg(ui_numb); QSqlQuery query; if(query.exec(sql))// { QMessageBox::information(this,提示,修改数据成功); ui-numbedit-clear(); ui-nameedit-clear(); ui-sexedit-clear(); ui-scoreedit-clear(); return; } else { QMessageBox::information(this,提示,修该数据失败); query.lastError(); return; } } //lasrError void Widget::on_delbtn_clicked() { ui-tableWidget-clear(); int ui_numbui-numbedit-text().toUInt(); if( ui_numb0 ) { QMessageBox::information(this,提示,请填写正确学号); return; } QString sql QString(delete from Stu where numb%1;).arg(ui_numb); QSqlQuery query; if(query.exec(sql))// { QMessageBox::information(this,提示,删除数据成功); ui-numbedit-clear(); ui-nameedit-clear(); ui-sexedit-clear(); ui-scoreedit-clear(); return; } else { QMessageBox::information(this,提示,删除数据失败); query.lastError(); return; } } void Widget::on_sortbtn_clicked() { // int ui_numbui-numbedit-text().toUInt(); // QMessageBox box(QMessageBox::Question,选择,请选择学号或者分数排序,QMessageBox::Ok|QMessageBox::Save); // box.setDefaultButton(QMessageBox::Ok); // box.setButtonText(QMessageBox::Ok,学号); // box.setButtonText(QMessageBox::Save,分数); // int res box.exec(); // QString sql; // if(resQMessageBox::Ok) // { // sql QString(select * from Stu order by numb asc); // } // else if(resQMessageBox::Save) // { // sql QString(select * from Stu order by score asc); // } QString sqlselect * from Stu ORDER BY score;; QSqlQuery query; ui-tableWidget-clear(); if(query.exec(sql))// { QMessageBox::information(this,提示,更改排序成功); ui-numbedit-clear(); ui-nameedit-clear(); ui-sexedit-clear(); ui-scoreedit-clear(); return; } else { QMessageBox::information(this,提示,更改排序失败); query.lastError(); return; } }