Qt TCP實(shí)現(xiàn)簡單通信功能
本文實(shí)例為大家分享了Qt TCP實(shí)現(xiàn)簡單通信的具體代碼,供大家參考,具體內(nèi)容如下
在.pro文件中添加網(wǎng)絡(luò)模塊 Qt += network
服務(wù)端:
1. 創(chuàng)建QTcpServer 對象,用于監(jiān)聽,創(chuàng)建套接字等;
QTcpServer * serverSocket = new QTcpServer(this);
2.進(jìn)行監(jiān)聽,通過QTcpServer對象 QTcpServer::listen();
bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);
例子:
// 獲取單行輸入框輸入的數(shù)為端口號 short port = ui->lineEdit->text().toInt(); tcpServer->listen(QHostAddress::Any, port); // QHostAddress::Any表示自動綁定
3.使用信號槽,connect(), 判斷是否有客戶端來連接,QTcpServer::newConnection();
[signal] void QTcpServer::newConnection()
例子:
// 3.基于 QTcpServer::newConnection() 信號檢測是否有新客戶端連接 connect(tcpServer, &QTcpServer::newConnection, this, [=]() ? ? { ? ? ? ? // 創(chuàng)建用于通信的套接字 ? ? ? ? // 4.如果有新的客戶端連接調(diào)用 QTcpSocket* QTcpServer::nextPendingConnection() ? ? ? ? // 在通信編輯框中顯示成功與客戶端取得連接 ? ? ? ? // 5.準(zhǔn)備與客戶端通信 ? ? ? ? // 6.判斷客戶端是否斷開連接 ? ? ? ? });
4.在步驟3的基礎(chǔ)上,創(chuàng)建套接字,QTcpSocket socketServer = QTcpServer::nextPendingConnection();
5.在步驟3的基礎(chǔ)上,使用信號槽connect(),判斷是否接收客戶端發(fā)了 的信息QTcpSocket::readyRead();
6. 在步驟5的基礎(chǔ)上,通過套接字調(diào)用readAll() ,讀取客戶端發(fā)來的信息;
7.在步驟3的基礎(chǔ)上,通過套接字判斷客戶端是否下線,關(guān)閉套接字;
客戶端:
1. 創(chuàng)建套接字對象,用于通信 QTcpSocket *clientSocket = new QTcpSocket(this);
2. 調(diào)用信號槽,connect() ,判斷是否成功連接服務(wù)端connected;
3. 調(diào)用信號槽,connect() , 判斷是否接受來著服務(wù)端發(fā)來的信息 readyRead();
4. 在步驟3的基礎(chǔ)上,利用套接字對象調(diào)用readAll() 方法,讀取服務(wù)端發(fā)來的消息;
5. 利用套接字調(diào)用write() 方法,將消息發(fā)送給服務(wù)端;
6. 調(diào)用信號槽,connect() , 判斷是否斷開連接,釋放套接字;
服務(wù)端代碼:
MainWindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" ? #include "QDebug" #include <QMessageBox> ? MainWindow::MainWindow(QWidget *parent) : ? ? QMainWindow(parent), ? ? ui(new Ui::MainWindow) { ? ? ui->setupUi(this); ? ? ? // 設(shè)置窗口名稱 ? ? setWindowTitle(QString("Server-TCP")); ? ? setWindowIcon(QIcon(QPixmap("D:\\BaiduNetdiskDownload\\Res WWW\\picture\\ico\\01_副本.png"))); ? ? ? // 剛進(jìn)來是將連接狀態(tài)圖片置成灰色的 ? ? m_pixmap.load(QString("D:\\BaiduNetdiskDownload\\Res WWW\\picture\\ico\\01_副本_副本.png")); ? ? ? // 2.socket 通信 ? ? //tcpSocket = new QTcpSocket(); ? ? // 獲取套接字 ? ? // 服務(wù)端通信流程 ? ? // 1.創(chuàng)建套接字服務(wù)器 QTcpServer對象 ? ? tcpServer = new QTcpServer(this); ? ? // 2.通過QTcpServer對象設(shè)置監(jiān)聽,即QTcpServer::listen() ? ? // 3.基于 QTcpServer::newConnection() 信號檢測是否有新客戶端連接 ? ? connect(tcpServer, &QTcpServer::newConnection, this, [=]() ? ? { ? ? ? ? // 成功連接則切換圖片顏色 ? ? ? ? m_pixmap.load(QString("D:\\BaiduNetdiskDownload\\Res WWW\\picture\\ico\\01_副本.png")); ? ? ? ? ? // 創(chuàng)建用于通信的套接字 ? ? ? ? // 4.如果有新的客戶端連接調(diào)用 QTcpSocket* QTcpServer::nextPendingConnection() ? ? ? ? tcpSocket = tcpServer->nextPendingConnection(); ? ? ? ? // 在通信編輯框中顯示成功與客戶端取得連接 ? ? ? ? ui->textEdit->append("成功與客戶端取得連接!!!"); ? ? ? ? // 5.準(zhǔn)備與客戶端通信 ? ? ? ? connect(tcpSocket, &QTcpSocket::readyRead, this, [=]() ? ? ? ? { ? ? ? ? ? ? // 調(diào)用套接字讀取客戶端發(fā)的數(shù)據(jù) ? ? ? ? ? ? QString acceptText = tcpSocket->readAll(); // QByteArray 可以強(qiáng)制轉(zhuǎn)成 QString ? ? ? ? ? ? // 將讀取到的數(shù)據(jù)寫到通信編輯框中 ? ? ? ? ? ? ui->textEdit->append("客戶端say:" + acceptText); ? ? ? ? }); ? ? ? ? ? // 6.判斷客戶端是否斷開連接 ? ? ? ? connect(tcpSocket, &QTcpSocket::disconnected, this, [=]() ? ? ? ? { ? ? ? ? ? ? //QMessageBox(, QMessageBox::Warning, ); ? ? ? ? ? ? QMessageBox::warning(this, "連接狀態(tài)", "客戶端已斷開連接"); ? ? ? ? ? ? tcpSocket->deleteLater(); ? ? ? ? ? ? // 將連接狀態(tài)圖片置成灰色的 ? ? ? ? ? ? m_pixmap.load(QString("D:\\BaiduNetdiskDownload\\Res WWW\\picture\\ico\\01_副本_副本.png")); ? ? ? ? ? ? ? //tcpServer->deleteLater(); ? ? ? ? }); ? ? ? }); ? ? ? // 1.狀態(tài)欄顯示信息 ? ? showMessageStatusBar(); } ? MainWindow::~MainWindow() { ? ? delete ui; } ? // 狀態(tài)欄添加提示信息 void MainWindow::showMessageStatusBar() { ? ? // 設(shè)置窗口名稱 ? ? //QWidget::windowTitleChanged("Server-TCP"); ? ? //ui->statusBar->setWindowTitle(); ? ? ? // 通過加載QLable給狀態(tài)欄顯示文本 ? ? QLabel *pLable = new QLabel(); ? ? QLabel *lableText = new QLabel(QString::fromUtf8("連接狀態(tài):")); ? ? ? //lableText->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); ? ? //pLable->setMinimumWidth(this->width()/2); ? ? ? //= new QLabel(QString::fromUtf8("連接狀態(tài):")); ? ? // 設(shè)置lable標(biāo)簽的大小 ? ? //pLable->setMinimumSize(pLable->sizeHint()); ? ? pLable->setFixedSize(30, 30); ? ? ? m_pixmap.scaled(pLable->width(), pLable->height()); ? ? // 顯示圖片 ? ? pLable->setPixmap(m_pixmap); ? ? // 按比例縮小圖片 ? ? ? //pLable->setFixedSize(QSize(50,50)); ? ? // 設(shè)置狀態(tài)欄樣式 ? ? //ui->statusBar->setStyleSheet(QString("QString::item{border:0px")); ?// 不顯示邊框 ? ? // 將標(biāo)簽加入到狀態(tài)欄中 ? ? ui->statusBar->addWidget(lableText); ? ? ui->statusBar->addPermanentWidget(pLable);// } ? // 處理點(diǎn)擊啟動服務(wù)器,進(jìn)行監(jiān)聽 void MainWindow::on_pushButton_clicked() { ? ? //qDebug() << "點(diǎn)擊了 啟動服務(wù)器按鈕\n"; ? ? // 獲取輸入框輸入的數(shù)為端口號 ? ? short port = ui->lineEdit->text().toInt(); ? ? tcpServer->listen(QHostAddress::Any, port); } ? // 將數(shù)據(jù)發(fā)生給客戶端 void MainWindow::on_pushButton_2_clicked() { ? ? // 將發(fā)送數(shù)據(jù)編輯欄的文本通過套接字發(fā)生給客戶端 ? ? tcpSocket->write(ui->textEdit_2->toPlainText().toUtf8()); ? ? // 需要將要發(fā)生的數(shù)據(jù)寫到通信編輯欄中 ? ? ui->textEdit->append("服務(wù)端say:" + ui->textEdit_2->toPlainText().toUtf8()); ? ? // 清空發(fā)送消息編輯框 ? ? ui->textEdit_2->clear(); }
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 = nullptr); ? ? ~MainWindow(); ? ? ? // 在狀態(tài)欄中設(shè)置文本+圖標(biāo) ? ? void showMessageStatusBar(); ? ? ? QTcpServer* tcpServer; ? ? QTcpSocket* tcpSocket; ? private slots: ? ? void on_pushButton_clicked(); ? ? ? void on_pushButton_2_clicked(); ? private: ? ? Ui::MainWindow *ui; ? ? // 用于加載圖片路徑 ? ? QPixmap m_pixmap; }; ? #endif // MAINWINDOW_H
程序UI
客戶端:
client.cpp
#include "client.h" #include "ui_client.h" ? Client::Client(QWidget *parent) : ? ? QMainWindow(parent), ? ? ui(new Ui::Client) { ? ? ui->setupUi(this); ? ? ? // 通信流程 ? ? //1、創(chuàng)建套接字對象 ? ? clientSocket = new QTcpSocket(this); ? ? //2、調(diào)用QTcpSocket::connectToHost() 綁定服務(wù)端IP和端口 ? ? ? //3、通過套接字與服務(wù)端進(jìn)行通信 收發(fā) ? ? // 判斷是否成功連接服務(wù)端 開始讀取服務(wù)端發(fā)來的信息 ? ? connect(clientSocket, &QTcpSocket::readyRead, this, [=]() ? ? { ? ? ? ? // 通過套接字讀取發(fā)來的信息 ? ? ? ? QByteArray receiveAll = clientSocket->readAll(); ? ? ? ? // 將獲取到的信息顯示到通信編輯欄中 ? ? ? ? ui->textEdit_Record->append("服務(wù)端say:" + receiveAll); ? ? }); ? ? ? // 開始的時候斷開連接按鈕置成不可用狀態(tài) ? ? ui->disConBtn->setEnabled(false); ? ? ? // 判斷是否連接成功 ? ? connect(clientSocket, &QTcpSocket::connected, this, [=]() ? ? { ? ? ? ? // 將成功連接顯示到通信記錄編輯欄中 ? ? ? ? ui->textEdit_Record->append("成功與服務(wù)端取得連接!!!"); ? ? ? ? // 將斷開連接置成可用狀態(tài) ? ? ? ? ui->disConBtn->setEnabled(true); ? ? }); ? ? ? // 判斷是否斷開連接 ? ? connect(clientSocket, &QTcpSocket::disconnected, this, [=]() ? ? { ? ? ? ? // 將服務(wù)端斷開連接顯示到通信編輯框中 ? ? ? ? ui->textEdit_Record->append("注意服務(wù)端已斷開連接!!!"); ? ? ? ? // 將連接服務(wù)端按鈕置成不可用狀態(tài) ? ? ? ? ui->conBtn->setEnabled(false); ? ? }); ? } ? Client::~Client() { ? ? delete ui; } ? // 點(diǎn)擊按鈕連接服務(wù)器,綁定地址與端口 void Client::on_conBtn_clicked() { ? ? // 獲取編輯框中的ip和端口 ? ? unsigned short port = ui->lineEdit_port->text().toUShort(); ? ? QString addr = ui->lineEdit_add->text(); ? ? clientSocket->connectToHost(addr, port); ? ? // 需要將按鈕置成不可用狀態(tài) ? ? ui->conBtn->setEnabled(false); } ? // 斷開連接 void Client::on_disConBtn_clicked() { ? ? //clientSocket->disconnected(); ? ? // 關(guān)閉套接字 ? ? clientSocket->close(); ? ? // 將客戶端斷開連接提示顯示到通信編輯框中 ? ? ui->textEdit_Record->append("注意客戶端已斷開連接!!!"); ? ? // 將連接服務(wù)端按鈕置成可用狀態(tài) ? ? ui->conBtn->setEnabled(true); } ? // 點(diǎn)擊按鈕發(fā)送數(shù)據(jù) void Client::on_sendBtn_clicked() { ? ? // 獲取發(fā)送信息編輯框的文本 ? ? //ui->textEdit_Send->toPlainText().toUtf8(); ? ? ? // 將獲取到的信息發(fā)送給服務(wù)端 ? ? clientSocket->write(ui->textEdit_Send->toPlainText().toUtf8()); ? ? // 將發(fā)送的信息顯示到通信記錄編輯框中 ? ? ui->textEdit_Record->append(ui->textEdit_Send->toPlainText().toUtf8()); ? ? // 需要將發(fā)送編輯框清空緩存 ? ? ui->textEdit_Send->clear(); }
client.h
#ifndef CLIENT_H #define CLIENT_H ? #include <QMainWindow> #include <QTcpSocket> ? namespace Ui { class Client; } ? class Client : public QMainWindow { ? ? Q_OBJECT ? public: ? ? explicit Client(QWidget *parent = nullptr); ? ? ~Client(); ? private slots: ? ? void on_conBtn_clicked(); ? ? ? void on_disConBtn_clicked(); ? ? ? void on_sendBtn_clicked(); ? private: ? ? Ui::Client *ui; ? ? ? // 創(chuàng)建套接字 ? ? QTcpSocket * clientSocket; }; ? #endif // CLIENT_H
程序UI
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于Matlab實(shí)現(xiàn)數(shù)字音頻分析處理系統(tǒng)
這篇文章主要為大家介紹了如何利用Matlab制作一個帶GUI的數(shù)字音頻分析與處理系統(tǒng)。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下2022-02-02C++實(shí)現(xiàn)LeetCode(47.全排列之二)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(47.全排列之二),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C++有限狀態(tài)機(jī)實(shí)現(xiàn)詳解
這篇文章主要為大家詳細(xì)介紹了C++有限狀態(tài)機(jī)的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10