主页 > 互联网  > 

通信TCP

通信TCP
TCP 通信流程服务器客户端

TCP

在 Qt 中,QTcpServer 和 QTcpSocket 是用于实现 TCP 网络通信的核心类。QTcpServer 用于创建 TCP 服务器,监听客户端的连接请求;QTcpSocket 用于实现客户端和服务器之间的数据传输。

通信流程

服务器

创建套接字服务器QTcpServer对象通过QTcpServer对象设置监听,即:QTcpServer::listen()基于QTcpServer::newConnection()信号检测是否有新的客户端连接如果有新的客户端连接调用QTcpSocket *QTcpServer::nextPendingConnection()得到通信的套接字对象使用通信的套接字对象QTcpSocket和客户端进行通信 #include "mainwindow.h" #include "ui_mainwindow.h" #include<QMessageBox> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); tcpserver = new QTcpServer(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_openBt_clicked() { quint16 port = ui->portEdit->text().toUInt(); // 获取端口号 if (port == 0 || port > 65535) { QMessageBox::warning(this, "错误", "端口号无效!"); return; } if (!tcpserver->listen(QHostAddress::Any, port)) { QMessageBox::warning(this, "错误", "服务器启动失败!"); return; } QMessageBox::information(this, "成功", "服务器已启动!"); connect(tcpserver, &QTcpServer::newConnection, this, [=]() { QTcpSocket *socket = tcpserver->nextPendingConnection(); clientSockets.append(socket); // 将新客户端 socket 加入列表 // 处理客户端数据 connect(socket, &QTcpSocket::readyRead, this, [=]() { QByteArray data = socket->readAll(); ui->recvEdit->appendPlainText("客户端 say:" + data); }); // 处理客户端断开连接 connect(socket, &QTcpSocket::disconnected, this, [=]() { clientSockets.removeOne(socket); // 从列表中移除 socket->deleteLater(); // 释放资源 }); }); } void MainWindow::on_sendBt_clicked() { // 获取输入框中的文本 QString str = ui->sendEdit->text(); // 假设 sendEdit 是 QLineEdit if (str.isEmpty()) { QMessageBox::warning(this, "错误", "发送内容不能为空!"); return; } // 将 QString 转换为 QByteArray QByteArray data = str.toUtf8(); // 遍历所有客户端 socket,发送数据 for (QTcpSocket *socket : clientSockets) { if (socket->state() == QAbstractSocket::ConnectedState) {// 是用于检查 QTcpSocket 是否处于连接状态的条件。 socket->write(data); // 发送数据 } } // 清空输入框 ui->sendEdit->clear(); } void MainWindow::on_closeBt_clicked() { // 关闭服务器,停止监听 tcpserver->close(); // 断开所有客户端连接 for (QTcpSocket *socket : clientSockets) { if (socket->state() == QAbstractSocket::ConnectedState) { socket->disconnectFromHost(); // 断开连接 } socket->deleteLater(); // 释放资源 } // 清空客户端列表 clientSockets.clear(); // 更新 UI 状态 QMessageBox::information(this, "成功", "服务器已关闭!"); ui->recvEdit->appendPlainText("服务器已关闭!"); }

头文件

#include <QTcpServer> #include <QTcpSocket> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_openBt_clicked(); void on_sendBt_clicked(); void on_closeBt_clicked(); private: Ui::MainWindow *ui; QTcpServer *tcpserver; QList<QTcpSocket*> clientSockets; // 保存所有客户端连接的 socket 列表 }; 客户端 创建通信的套接字类QTcpSocket对象使用服务器端绑定的IP和端口连接服务器QAbstractSocket::connectToHost()使用QTcpSocket对象和服务器进行通信 #include "ui_mainwindow.h" #include<QMessageBox> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); tcpsocket = new QTcpSocket(this); // 连接 socket 的信号和槽 connect(tcpsocket, &QTcpSocket::connected, this, [=]() { QMessageBox::information(this, "成功", "已连接到服务器!"); ui->recvEdit->appendPlainText("已连接到服务器!"); }); connect(tcpsocket, &QTcpSocket::disconnected, this, [=]() { QMessageBox::information(this, "提示", "已断开与服务器的连接!"); ui->recvEdit->appendPlainText("已断开与服务器的连接!"); }); connect(tcpsocket, &QTcpSocket::readyRead, this, [=]() { QByteArray data = tcpsocket->readAll(); ui->recvEdit->appendPlainText("服务器 say: " + QString::fromUtf8(data)); }); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_connect_clicked() { // 获取服务器地址和端口号 QString address = ui->IPEdit->text(); quint16 port = ui->portEdit->text().toUInt(); if (address.isEmpty() || port == 0) { QMessageBox::warning(this, "错误", "服务器地址或端口号无效!"); return; } // 连接到服务器 tcpsocket->connectToHost(address, port); // 检查连接状态 if (!tcpsocket->waitForConnected(1000)) { QMessageBox::warning(this, "错误", "连接服务器超时!"); } } void MainWindow::on_disconnect_clicked() { // 断开与服务器的连接 if (tcpsocket->state() == QAbstractSocket::ConnectedState) { tcpsocket->disconnectFromHost(); } } void MainWindow::on_sendBt_clicked() { // 获取输入框中的文本 QString str = ui->sendEdit->text(); // 假设 sendEdit 是 QLineEdit if (str.isEmpty()) { QMessageBox::warning(this, "错误", "发送内容不能为空!"); return; } // 将 QString 转换为 QByteArray QByteArray data = str.toUtf8(); // 发送数据 if (tcpsocket->state() == QAbstractSocket::ConnectedState) { tcpsocket->write(data); } else { QMessageBox::warning(this, "错误", "未连接到服务器!"); } // 清空输入框 ui->sendEdit->clear(); }

头文件

#include <QTcpSocket> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_sendBt_clicked(); void on_connect_clicked(); void on_disconnect_clicked(); private: Ui::MainWindow *ui; QTcpSocket* tcpsocket; // 保存所有客户端连接的 socket 列表 };

 

作者: 苏丙榅 链接: 基于TCP的Qt网络通信 | 爱编程的大丙 来源: 爱编程的大丙 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

标签:

通信TCP由讯客互联互联网栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“通信TCP