QT5实现简单的TCP通信

瑟寒凌风 2018-10-23 10:05:25
9282
收藏 56
分类专栏: QT开发
原文https://blog.youkuaiyun.com/u014695839/article/details/70041771/
这段时间用到了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的设计:

本文介绍了如何使用QT5进行TCP通信,包括客户端通过QTcpSocket连接服务器、发送数据和接收数据,以及服务器端的相应处理。实例代码详细展示了如何在QT环境中建立和维护TCP连接,适合初学者入门。
9470

被折叠的 条评论
为什么被折叠?



