国庆10.4
- 电脑硬件
- 2025-08-18 01:12:02

QT实现TCP服务器客户端
服务器
头文件
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QTcpServer> //服务器头文件 #include <QTcpSocket> //客户端头文件 #include <QList> //链表容器 #include <QMessageBox> //消息对话框 #include <QDebug> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private slots: void on_startBtn_clicked(); void newConnection_slot(); //自定义处理newConnection信号槽函数的声明 void readyRead_slot(); //自定义处理readyRead信号的槽函数的声明 private: Ui::Widget *ui; //定义服务器指针 QTcpServer *server; //定义客户端容器 QList<QTcpSocket *> clientList; }; #endif // WIDGET_H源文件
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); //实例化一个服务器 server = new QTcpServer(this); connect(server, &QTcpServer::newConnection, this, &Widget::newConnection_slot); } Widget::~Widget() { delete ui; } //启动服务器按钮对应的槽函数 void Widget::on_startBtn_clicked() { quint16 port = ui->portEdit->text().toUInt(); //获取ui界面上的端口号 //监听客户端的连接请求 if(!server->listen(QHostAddress::Any, port)) { QMessageBox::information(this, "失败", "监听失败"); }else { QMessageBox::information(this, "成功", "服务器启动成功"); } } //自定义处理newConnection信号的槽函数的实现 void Widget::newConnection_slot() { qDebug()<<"您有新的客户端发来连接请求了"; //获取最新连接的客户端套接字 QTcpSocket *s = server->nextPendingConnection(); //将该套接字,放入客户端链表中 clientList.push_back(s); //至此,多个客户端已经跟服务器建立连接,并放入客户端容器中了 connect(s, &QTcpSocket::readyRead, this, &Widget::readyRead_slot); } //readyRead信号对应槽函数的实现 void Widget::readyRead_slot() { //可以添加提示音 qDebug()<<"有新的客户端消息发来了"; //遍历客户端链表,将无效的客户端移除 for(int i=0; i<clientList.size(); i++) { //判断当前套接字是否是有效连接 if(clientList[i]->state() == 0) { //将该套接字移除客户端容器(链表 clientList.removeAt(i); } } //遍历客户端链表,判断是哪个客户端发来的数据 for(int i=0; i<clientList.size(); i++) { if(clientList[i]->bytesAvailable() != 0) { //将该套接字中的数据读取出来 QByteArray msg = clientList[i]->readAll(); //将数据展示到ui界面 ui->msgWidget->addItem( QString::fromLocal8Bit(msg) ); //将接收到的数据,转发给所有客户端 for(int j=0; j<clientList.size(); j++) { clientList[j]->write(msg); } } } }客户端
头文件
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QTcpSocket> //客户端类 #include <QMessageBox> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private slots: void on_connectBtn_clicked(); void connected_slot(); //自定义处理connected信号的槽函数 void readyRead_slot(); void on_sendBtn_clicked(); void on_disconnectBtn_clicked(); void disconnected_slot(); //自定义处理disconnected信号的槽函数声明 private: Ui::Widget *ui; //定义客户端指针 QTcpSocket *socket; //定义字符串接收用户 QString userName; }; #endif // WIDGET_H源文件
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); //给客户端指针实例化对象 socket = new QTcpSocket(this); //由于只需要连接一次,所以将连接写在构造函数中 connect(socket, &QTcpSocket::connected, this, &Widget::connected_slot); //如果服务器向客户端发来消息,那么该客户端就会自动发射一个readyRead信号 connect(socket, &QTcpSocket::readyRead, this, &Widget::readyRead_slot); //当成功与服务器断开连接后,该客户端会自动发射一个disconnected的信号 connect(socket, &QTcpSocket::disconnected, this, &Widget::disconnected_slot); } Widget::~Widget() { delete ui; } //连接服务器按钮对应的槽函数 void Widget::on_connectBtn_clicked() { //获取ui界面上的相关信息 userName = ui->userNameEdit->text(); //获取用户名 QString ip = ui->ipEdit->text(); //主机地址 quint16 port = ui->portEdit->text().toUInt(); //端口号 socket->connectToHost(ip, port); } //处理connected信号的槽函数的定义 void Widget::connected_slot() { QMessageBox::information(this, "成功", "您已经成功进入聊天室"); //向服务器发送一条数据: ***:进入聊天室 QString msg = userName +": 进入聊天室"; socket->write(msg.toLocal8Bit()); //将数据写给服务器 } //处理readyRead信号的槽函数的定义 void Widget::readyRead_slot() { //读取套接字中的信息 QByteArray msg = socket->readAll(); //将数据展示到ui界面 ui->msgWidget->addItem(QString::fromLocal8Bit(msg)); } //发送按钮对应的槽函数 void Widget::on_sendBtn_clicked() { //获取ui界面输入的内容 QString msg = userName+ ": " + ui->msgEdit->text(); //发送给服务器 socket->write(msg.toLocal8Bit()); //清空编辑框内容 ui->msgEdit->clear(); } //断开服务器按钮对应的槽函数 void Widget::on_disconnectBtn_clicked() { //告诉大家 我走了 QString msg = userName +": 离开聊天室"; socket->write(msg.toLocal8Bit()); //断开连接 socket->disconnectFromHost(); } //disconnected信号对应槽函数的定义 void Widget::disconnected_slot() { QMessageBox::information(this, "提示", "退出成功"); }现象
上一篇
JavaEE改Jakarta