網站首頁 編程語言 正文
這段時間用到了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的設計:
三、運行結果
附上兩個工程的下載鏈接:tcp_QT_jb51.rar
原文鏈接:https://blog.csdn.net/u014695839/article/details/70041771
相關推薦
- 2022-09-07 Python解析pcap文件示例_python
- 2024-03-04 layui表單重置按鈕不生效的問題
- 2021-12-03 C++類和對象實戰之Date類的實現方法_C 語言
- 2023-05-20 pytorch中forwod函數在父類中的調用方式解讀_python
- 2022-06-09 使用FreeRTOS遇到死等異常的解決_操作系統
- 2022-07-08 Python如何讀取csv文件時添加表頭/列名_python
- 2022-11-02 Python+eval函數實現動態地計算數學表達式詳解_python
- 2022-10-17 C#使用集合實現二叉查找樹_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支