<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
這段時間用到了QT的TCP通訊,做了初步的學習與嘗試,編寫了一個使用者端和伺服器基於視窗通訊的小例程。
使用QT的網路通訊端需要.pro檔案中加入一句:
QT += network
1、使用者端的程式碼比伺服器稍簡單,總的來說,使用QT中的QTcpSocket類與伺服器進行通訊只需要以下5步:
(1)建立QTcpSocket通訊端物件
socket = new QTcpSocket();
(2)使用這個物件連線伺服器
socket->connectToHost(IP, port);
(3)使用write函數向伺服器傳送資料
socket->write(data);
(4)當socket接收緩衝區有新資料到來時,會發出readRead()訊號,因此為該訊號新增槽函數以讀取資料
QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data); void MainWindow::socket_Read_Data() { QByteArray buffer; //讀取緩衝區資料 buffer = socket->readAll(); }
(5)斷開與伺服器的連線(關於close()和disconnectFromHost()的區別,可以按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(); //連線伺服器 socket->connectToHost(IP, port); //等待連線成功 if(!socket->waitForConnected(30000)) { qDebug() << "Connection failed!"; return; } qDebug() << "Connect successfully!"; //傳送按鍵使能 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(); //獲取文字方塊內容並以ASCII碼形式傳送 socket->write(ui->textEdit_Send->toPlainText().toLatin1()); socket->flush(); } void MainWindow::socket_Read_Data() { QByteArray buffer; //讀取緩衝區資料 buffer = socket->readAll(); if(!buffer.isEmpty()) { QString str = ui->textEdit_Recv->toPlainText(); str+=tr(buffer); //重新整理顯示 ui->textEdit_Recv->setText(str); } } void MainWindow::socket_Disconnected() { //傳送按鍵失能 ui->pushButton_Send->setEnabled(false); //修改按鍵文字 ui->pushButton_Connect->setText("連線"); qDebug() << "Disconnected!"; }
最後是ui的設計:
1、伺服器除了使用到了QTcpSocket類,還需要用到QTcpSever類。即便如此,也只是比使用者端複雜一點點,用到了6個步驟:
(1)建立QTcpSever物件
server = new QTcpServer();
(2)偵聽一個埠,使得使用者端可以使用這個埠存取伺服器
server->listen(QHostAddress::Any, port);
(3)當伺服器被使用者端存取時,會發出newConnection()訊號,因此為該訊號新增槽函數,並用一個QTcpSocket物件接受使用者端存取
connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect); void MainWindow::server_New_Connect() { //獲取使用者端連線 socket = server->nextPendingConnection(); }
(4)使用socket的write函數向用戶端傳送資料
socket->write(data);
(5)當socket接收緩衝區有新資料到來時,會發出readRead()訊號,因此為該訊號新增槽函數以讀取資料
QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data); void MainWindow::socket_Read_Data() { QByteArray buffer; //讀取緩衝區資料 buffer = socket->readAll(); }
(6)取消偵聽
server->close();
2、以下是伺服器的例程
首先是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(); //監聽指定的埠 if(!server->listen(QHostAddress::Any, port)) { //若出錯,則輸出錯誤資訊 qDebug()<<server->errorString(); return; } //修改按鍵文字 ui->pushButton_Listen->setText("取消偵聽"); qDebug()<< "Listen succeessfully!"; } else { /* //如果正在連線(點選偵聽後立即取消偵聽,若socket沒有指定物件會有異常,應修正——2017.9.30) if(socket->state() == QAbstractSocket::ConnectedState) { //關閉連線 socket->disconnectFromHost(); } */ socket->abort(); //取消偵聽 server->close(); //修改按鍵文字 ui->pushButton_Listen->setText("偵聽"); //傳送按鍵失能 ui->pushButton_Send->setEnabled(false); } } void MainWindow::on_pushButton_Send_clicked() { qDebug() << "Send: " << ui->textEdit_Send->toPlainText(); //獲取文字方塊內容並以ASCII碼形式傳送 socket->write(ui->textEdit_Send->toPlainText().toLatin1()); socket->flush(); } void MainWindow::server_New_Connect() { //獲取使用者端連線 socket = server->nextPendingConnection(); //連線QTcpSocket的訊號槽,以讀取新資料 QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data); QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected); //傳送按鍵使能 ui->pushButton_Send->setEnabled(true); qDebug() << "A Client connect!"; } void MainWindow::socket_Read_Data() { QByteArray buffer; //讀取緩衝區資料 buffer = socket->readAll(); if(!buffer.isEmpty()) { QString str = ui->textEdit_Recv->toPlainText(); str+=tr(buffer); //重新整理顯示 ui->textEdit_Recv->setText(str); } } void MainWindow::socket_Disconnected() { //傳送按鍵失能 ui->pushButton_Send->setEnabled(false); qDebug() << "Disconnected!"; }
最後是ui的設計:
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45