上一個blog說了C++的實現方法,但是大黑框的顯示未免顯得有點太過於不美觀,此次具體采用QT的方式進行實現,大致上的流程是這樣的:
參考上面的流程圖,大致上的實現模式就是這樣,但是TCP通信的全雙工的形式,所以收發信息的操作對客戶端還是服務端而言都i是一樣的,所以我們看看代碼的實現模式:
首先是TCP的實現
1.先創建這樣
然后一路往下點擊下一步:
需要注意的是在這里我們選擇這個:
接着看看代碼:serverWidget.h
#ifndef SERVERWIDGET_H #define SERVERWIDGET_H #include <QWidget> #include<QTcpServer>//監聽套接字 #include<QTcpSocket>//通信套接字 QT_BEGIN_NAMESPACE namespace Ui { class serverWidget; } QT_END_NAMESPACE class serverWidget : public QWidget { Q_OBJECT public: serverWidget(QWidget *parent = nullptr); ~serverWidget(); private slots: void on_pushButton_read_clicked(); void on_pushButton_write_clicked(); void on_pushButton_close_clicked(); private: Ui::serverWidget *ui; QTcpServer *server; QTcpSocket *socket_ser; }; #endif // SERVERWIDGET_H
serverWidget.cpp
#include "serverwidget.h" #include "ui_serverwidget.h" #include<QDebug> #include<QtNetwork> serverWidget::serverWidget(QWidget *parent) : QWidget(parent) , ui(new Ui::serverWidget) { server=new QTcpServer(this); ui->setupUi(this); bool isok=server->listen(QHostAddress::Any,8888);//在QT中綁定和監聽都使用的是listen函數 if(isok) { QString str1="監聽成功。。。。。"; ui->textEdit_read->setText(str1); //等待來自客戶端的鏈接觸發一個事件Connect action connect(server,&QTcpServer::newConnection, [=]() { //配置上通信套接字 socket_ser=server->nextPendingConnection(); //獲得對方的端口和IP QString ip=socket_ser->peerAddress().toString(); qint16 port =socket_ser->peerPort(); ui->textEdit_read->setText(QString("端口是%1,ip地址是%2").arg(port).arg(ip)); //讀的時候會觸發一個信號readyRead(). connect(socket_ser,&QTcpSocket::readyRead, [=](){ //從通信的套接字中拿出內容 QByteArray array=socket_ser->readAll(); ui->textEdit_read->append(array); } ); } ); } else { ui->textEdit_read->setText(QString("監聽失敗。。。。。")); } } serverWidget::~serverWidget() { delete ui; } void serverWidget::on_pushButton_write_clicked() { QString str=ui->textEdit_write->toPlainText(); socket_ser->write(str.toUtf8().data()); } void serverWidget::on_pushButton_close_clicked() { //進行套接字的關閉 socket_ser->disconnectFromHost();//通信套接字主動和端口斷開鏈接 server->close(); }
UI的設置是這樣的:
客戶端的UI也是這樣的設置
2.下面看看服務器的代碼
clientWidget.h
#ifndef CLIENTWIDGET_H #define CLIENTWIDGET_H #include <QWidget> #include<QTcpSocket> QT_BEGIN_NAMESPACE namespace Ui { class clientWidget; } QT_END_NAMESPACE class clientWidget : public QWidget { Q_OBJECT public: clientWidget(QWidget *parent = nullptr); ~clientWidget(); private slots: void on_pushButton_write_clicked(); void on_pushButton_close_clicked(); private: Ui::clientWidget *ui; QTcpSocket *socket_client; }; #endif // CLIENTWIDGET_H
clientWidget.cpp
#include "clientwidget.h" #include "ui_clientwidget.h" #include<QtNetwork> clientWidget::clientWidget(QWidget *parent) : QWidget(parent) , ui(new Ui::clientWidget) { ui->setupUi(this); socket_client=new QTcpSocket(this); socket_client->connectToHost("127.0.0.1",8888); //關於客戶端的讀取,客戶端本身就是一個通信套接字的形式進行信息的收發 connect(socket_client,&QTcpSocket::readyRead, [=](){ QByteArray array= socket_client->readAll(); ui->textEdit_read->append(array); }); } clientWidget::~clientWidget() { delete ui; } void clientWidget::on_pushButton_write_clicked() { QString mystring=ui->textEdit_write->toPlainText(); socket_client->write(mystring.toUtf8().data()); } void clientWidget::on_pushButton_close_clicked() { socket_client->disconnectFromHost(); }
【remark】
通過和上一個C++版本的對比,顯然可以看出QT的版本比較簡單容易實現,但是值得注意的是要在pro的文件里面加上“QT += network”,並且在CPP文件中加上
#include<QtNetwork>
詳細的運行結果如下: