QT5實(shí)現(xiàn)簡(jiǎn)單的TCP通信的實(shí)現(xiàn)
這段時(shí)間用到了QT的TCP通信,做了初步的學(xué)習(xí)與嘗試,編寫(xiě)了一個(gè)客戶端和服務(wù)器基于窗口通信的小例程。
使用QT的網(wǎng)絡(luò)套接字需要.pro文件中加入一句:
QT += network
一、客戶端
1、客戶端的代碼比服務(wù)器稍簡(jiǎn)單,總的來(lái)說(shuō),使用QT中的QTcpSocket類與服務(wù)器進(jìn)行通信只需要以下5步:
(1)創(chuàng)建QTcpSocket套接字對(duì)象
socket = new QTcpSocket();
(2)使用這個(gè)對(duì)象連接服務(wù)器
socket->connectToHost(IP, port);
(3)使用write函數(shù)向服務(wù)器發(fā)送數(shù)據(jù)
socket->write(data);
(4)當(dāng)socket接收緩沖區(qū)有新數(shù)據(jù)到來(lái)時(shí),會(huì)發(fā)出readRead()信號(hào),因此為該信號(hào)添加槽函數(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)斷開(kāi)與服務(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();
//連接信號(hào)槽
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();
//獲取端口號(hào)
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("斷開(kāi)連接");
}
else
{
//斷開(kāi)連接
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對(duì)象
server = new QTcpServer();
(2)偵聽(tīng)一個(gè)端口,使得客戶端可以使用這個(gè)端口訪問(wèn)服務(wù)器
server->listen(QHostAddress::Any, port);
(3)當(dāng)服務(wù)器被客戶端訪問(wèn)時(shí),會(huì)發(fā)出newConnection()信號(hào),因此為該信號(hào)添加槽函數(shù),并用一個(gè)QTcpSocket對(duì)象接受客戶端訪問(wèn)
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ù)到來(lái)時(shí),會(huì)發(fā)出readRead()信號(hào),因此為該信號(hào)添加槽函數(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)取消偵聽(tīng)
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();
//連接信號(hào)槽
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("偵聽(tīng)"))
{
//從輸入框獲取端口號(hào)
int port = ui->lineEdit_Port->text().toInt();
//監(jiān)聽(tīng)指定的端口
if(!server->listen(QHostAddress::Any, port))
{
//若出錯(cuò),則輸出錯(cuò)誤信息
qDebug()<<server->errorString();
return;
}
//修改按鍵文字
ui->pushButton_Listen->setText("取消偵聽(tīng)");
qDebug()<< "Listen succeessfully!";
}
else
{
/*
//如果正在連接(點(diǎn)擊偵聽(tīng)后立即取消偵聽(tīng),若socket沒(méi)有指定對(duì)象會(huì)有異常,應(yīng)修正——2017.9.30)
if(socket->state() == QAbstractSocket::ConnectedState)
{
//關(guān)閉連接
socket->disconnectFromHost();
}
*/
socket->abort();
//取消偵聽(tīng)
server->close();
//修改按鍵文字
ui->pushButton_Listen->setText("偵聽(tīng)");
//發(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的信號(hào)槽,以讀取新數(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)簡(jiǎn)單的TCP通信的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)QT5 TCP通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Qt中TCP協(xié)議通信詳解
- QT實(shí)現(xiàn)簡(jiǎn)單TCP通信
- Qt實(shí)現(xiàn)簡(jiǎn)單的TCP通信
- QT編寫(xiě)tcp通信工具(Client篇)
- QT網(wǎng)絡(luò)通信TCP客戶端實(shí)現(xiàn)詳解
- Qt?TCP網(wǎng)絡(luò)通信學(xué)習(xí)
- Qt網(wǎng)絡(luò)編程實(shí)現(xiàn)TCP通信
- 基于QT的TCP通信服務(wù)的實(shí)現(xiàn)
- QT網(wǎng)絡(luò)編程Tcp下C/S架構(gòu)的即時(shí)通信實(shí)例
- Qt TCP實(shí)現(xiàn)簡(jiǎn)單通信功能
相關(guān)文章
Qt實(shí)現(xiàn)制作簡(jiǎn)單的計(jì)算器
計(jì)算器是我們生活中很常見(jiàn)的東西,它可以由多種語(yǔ)言多種方式來(lái)實(shí)現(xiàn)。本文主要介紹的是利用Qt實(shí)現(xiàn)的簡(jiǎn)易計(jì)算器的制作,文中的示例代碼講解詳細(xì),需要的可以參考一下2022-12-12
C語(yǔ)言實(shí)現(xiàn)火車票管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)火車票管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
C++運(yùn)算符重載實(shí)例代碼詳解(調(diào)試環(huán)境 Visual Studio 2019)
這篇文章主要介紹了C++運(yùn)算符重載實(shí)例(調(diào)試環(huán)境 Visual Studio 2019),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03
利用C語(yǔ)言實(shí)現(xiàn)三子棋(井字棋)小游戲
這篇文章主要為大家詳細(xì)介紹了利用C語(yǔ)言實(shí)現(xiàn)三子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
C到C++的升級(jí)關(guān)系及區(qū)別實(shí)例探究
這篇文章主要為大家介紹了C到C++的升級(jí)關(guān)系及區(qū)別實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
Qt添加MSVC2017編譯器的實(shí)現(xiàn)方法
Qt添加MSVC2017編譯器是開(kāi)發(fā)者在Windows平臺(tái)上進(jìn)行Qt應(yīng)用程序開(kāi)發(fā)的重要步驟,本文詳細(xì)介紹了如何為Qt配置MSVC2017編譯器的具體步驟,感興趣的可以了解一下2023-09-09

