QT5實(shí)現(xiàn)簡單的TCP通信的實(shí)現(xiàn)
這段時(shí)間用到了QT的TCP通信,做了初步的學(xué)習(xí)與嘗試,編寫了一個(gè)客戶端和服務(wù)器基于窗口通信的小例程。
使用QT的網(wǎng)絡(luò)套接字需要.pro文件中加入一句:
QT += network
一、客戶端
1、客戶端的代碼比服務(wù)器稍簡單,總的來說,使用QT中的QTcpSocket類與服務(wù)器進(jìn)行通信只需要以下5步:
(1)創(chuàng)建QTcpSocket套接字對象
socket = new QTcpSocket();
(2)使用這個(gè)對象連接服務(wù)器
socket->connectToHost(IP, port);
(3)使用write函數(shù)向服務(wù)器發(fā)送數(shù)據(jù)
socket->write(data);
(4)當(dāng)socket接收緩沖區(qū)有新數(shù)據(jù)到來時(shí),會發(fā)出readRead()信號,因此為該信號添加槽函數(shù)以讀取數(shù)據(jù)
QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data); void MainWindow::socket_Read_Data() { QByteArray buffer; //讀取緩沖區(qū)數(shù)據(jù) buffer = socket->readAll(); }
(5)斷開與服務(wù)器的連接(關(guān)于close()和disconnectFromHost()的區(qū)別,可以按F1看幫助)
socket->disconnectFromHost();
2、以下是客戶端的例程
首先是mainwindow.h文件:
//mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTcpSocket> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_pushButton_Connect_clicked(); void on_pushButton_Send_clicked(); void socket_Read_Data(); void socket_Disconnected(); private: Ui::MainWindow *ui; QTcpSocket *socket; }; #endif // MAINWINDOW_H
然后是mainwindow.cpp文件:
//mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); socket = new QTcpSocket(); //連接信號槽 QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data); QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected); ui->pushButton_Send->setEnabled(false); ui->lineEdit_IP->setText("127.0.0.1"); ui->lineEdit_Port->setText("8765"); } MainWindow::~MainWindow() { delete this->socket; delete ui; } void MainWindow::on_pushButton_Connect_clicked() { if(ui->pushButton_Connect->text() == tr("連接")) { QString IP; int port; //獲取IP地址 IP = ui->lineEdit_IP->text(); //獲取端口號 port = ui->lineEdit_Port->text().toInt(); //取消已有的連接 socket->abort(); //連接服務(wù)器 socket->connectToHost(IP, port); //等待連接成功 if(!socket->waitForConnected(30000)) { qDebug() << "Connection failed!"; return; } qDebug() << "Connect successfully!"; //發(fā)送按鍵使能 ui->pushButton_Send->setEnabled(true); //修改按鍵文字 ui->pushButton_Connect->setText("斷開連接"); } else { //斷開連接 socket->disconnectFromHost(); //修改按鍵文字 ui->pushButton_Connect->setText("連接"); ui->pushButton_Send->setEnabled(false); } } void MainWindow::on_pushButton_Send_clicked() { qDebug() << "Send: " << ui->textEdit_Send->toPlainText(); //獲取文本框內(nèi)容并以ASCII碼形式發(fā)送 socket->write(ui->textEdit_Send->toPlainText().toLatin1()); socket->flush(); } void MainWindow::socket_Read_Data() { QByteArray buffer; //讀取緩沖區(qū)數(shù)據(jù) buffer = socket->readAll(); if(!buffer.isEmpty()) { QString str = ui->textEdit_Recv->toPlainText(); str+=tr(buffer); //刷新顯示 ui->textEdit_Recv->setText(str); } } void MainWindow::socket_Disconnected() { //發(fā)送按鍵失能 ui->pushButton_Send->setEnabled(false); //修改按鍵文字 ui->pushButton_Connect->setText("連接"); qDebug() << "Disconnected!"; }
最后是ui的設(shè)計(jì):
二、服務(wù)器
1、服務(wù)器除了使用到了QTcpSocket類,還需要用到QTcpSever類。即便如此,也只是比客戶端復(fù)雜一點(diǎn)點(diǎn),用到了6個(gè)步驟:
(1)創(chuàng)建QTcpSever對象
server = new QTcpServer();
(2)偵聽一個(gè)端口,使得客戶端可以使用這個(gè)端口訪問服務(wù)器
server->listen(QHostAddress::Any, port);
(3)當(dāng)服務(wù)器被客戶端訪問時(shí),會發(fā)出newConnection()信號,因此為該信號添加槽函數(shù),并用一個(gè)QTcpSocket對象接受客戶端訪問
connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect); void MainWindow::server_New_Connect() { //獲取客戶端連接 socket = server->nextPendingConnection(); }
(4)使用socket的write函數(shù)向客戶端發(fā)送數(shù)據(jù)
socket->write(data);
(5)當(dāng)socket接收緩沖區(qū)有新數(shù)據(jù)到來時(shí),會發(fā)出readRead()信號,因此為該信號添加槽函數(shù)以讀取數(shù)據(jù)
QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data); void MainWindow::socket_Read_Data() { QByteArray buffer; //讀取緩沖區(qū)數(shù)據(jù) buffer = socket->readAll(); }
(6)取消偵聽
server->close();
2、以下是服務(wù)器的例程
首先是mainwindow.h文件:
//mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #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_pushButton_Listen_clicked(); void on_pushButton_Send_clicked(); void server_New_Connect(); void socket_Read_Data(); void socket_Disconnected(); private: Ui::MainWindow *ui; QTcpServer* server; QTcpSocket* socket; }; #endif // MAINWINDOW_H
然后是mainwindow.cpp文件:
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ui->lineEdit_Port->setText("8765"); ui->pushButton_Send->setEnabled(false); server = new QTcpServer(); //連接信號槽 connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect); } MainWindow::~MainWindow() { server->close(); server->deleteLater(); delete ui; } void MainWindow::on_pushButton_Listen_clicked() { if(ui->pushButton_Listen->text() == tr("偵聽")) { //從輸入框獲取端口號 int port = ui->lineEdit_Port->text().toInt(); //監(jiān)聽指定的端口 if(!server->listen(QHostAddress::Any, port)) { //若出錯(cuò),則輸出錯(cuò)誤信息 qDebug()<<server->errorString(); return; } //修改按鍵文字 ui->pushButton_Listen->setText("取消偵聽"); qDebug()<< "Listen succeessfully!"; } else { /* //如果正在連接(點(diǎn)擊偵聽后立即取消偵聽,若socket沒有指定對象會有異常,應(yīng)修正——2017.9.30) if(socket->state() == QAbstractSocket::ConnectedState) { //關(guān)閉連接 socket->disconnectFromHost(); } */ socket->abort(); //取消偵聽 server->close(); //修改按鍵文字 ui->pushButton_Listen->setText("偵聽"); //發(fā)送按鍵失能 ui->pushButton_Send->setEnabled(false); } } void MainWindow::on_pushButton_Send_clicked() { qDebug() << "Send: " << ui->textEdit_Send->toPlainText(); //獲取文本框內(nèi)容并以ASCII碼形式發(fā)送 socket->write(ui->textEdit_Send->toPlainText().toLatin1()); socket->flush(); } void MainWindow::server_New_Connect() { //獲取客戶端連接 socket = server->nextPendingConnection(); //連接QTcpSocket的信號槽,以讀取新數(shù)據(jù) QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data); QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected); //發(fā)送按鍵使能 ui->pushButton_Send->setEnabled(true); qDebug() << "A Client connect!"; } void MainWindow::socket_Read_Data() { QByteArray buffer; //讀取緩沖區(qū)數(shù)據(jù) buffer = socket->readAll(); if(!buffer.isEmpty()) { QString str = ui->textEdit_Recv->toPlainText(); str+=tr(buffer); //刷新顯示 ui->textEdit_Recv->setText(str); } } void MainWindow::socket_Disconnected() { //發(fā)送按鍵失能 ui->pushButton_Send->setEnabled(false); qDebug() << "Disconnected!"; }
最后是ui的設(shè)計(jì):
三、運(yùn)行結(jié)果
附上兩個(gè)工程的下載鏈接:tcp_QT_jb51.rar
到此這篇關(guān)于QT5實(shí)現(xiàn)簡單的TCP通信的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)QT5 TCP通信內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++運(yùn)算符重載實(shí)例代碼詳解(調(diào)試環(huán)境 Visual Studio 2019)
這篇文章主要介紹了C++運(yùn)算符重載實(shí)例(調(diào)試環(huán)境 Visual Studio 2019),本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03C到C++的升級關(guān)系及區(qū)別實(shí)例探究
這篇文章主要為大家介紹了C到C++的升級關(guān)系及區(qū)別實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01Qt添加MSVC2017編譯器的實(shí)現(xiàn)方法
Qt添加MSVC2017編譯器是開發(fā)者在Windows平臺上進(jìn)行Qt應(yīng)用程序開發(fā)的重要步驟,本文詳細(xì)介紹了如何為Qt配置MSVC2017編譯器的具體步驟,感興趣的可以了解一下2023-09-09