8.1.3 TCP客户端通信过程:
通信套接字连接到主机,三次握手,握手成功后产生connected()信号,当服务器端向客户服务器端发送数据时,客户端会产生readyRead()信号,将会触发读取槽函数。
客户端.pro文件:
由于是网络通信应用,所以添加
QT += network
CONFIG +=C++11 //Lambda
客户端头文件:
客户端无需监听服务器端,所以只需要一个通信套接字,所以需要包含头文件:
#include <QTcpSocket> //通信套接字
定义通信套接字指针:
QTcpSocket *tcpSocket; //通信套接字
客户端.cpp文件:
1)、首先是需要两个行编辑区,分别输入IP和端口号
2)、需要一个按钮,用于连接服务器端
3)、需要两个文本编辑区,其中一个位只读属性,用于显示服务器端发送的数据。另一个作用是输入将要发送的数据。
4)、需要两个按键,一个是用于发送,另一个是用于断开客户端与服务器端的连接。
由于客户端使用通信套接字进行通信,通信套接字的定义形式为指针,所以需要在使用指针之前开辟指针分配空间,并指定父对象(用于程序结束时的内存回收):
tcpSocket = new QTcpSocket(this);
客户端输入IP地址和端口号之后,点击按钮connect和服务器端进行连接,连接的具体方式为:首先获取服务器的IP,也就是获取行编辑区的输入内容,然后是获取端口信号,然后将前两者作为传入参数使用连接函数与服务器进行连接:
void ClientWidget::on_buttonConnect_clicked()
{
//获取服务器ip和端口
QString ip = ui->lineEditIP->text();
qint16 port = ui->lineEditPort->text().toInt();
//主动和服务器建立连接
tcpSocket->connectToHost(QHostAddress(ip), port);
}
为了了解客户端与服务器端的连接情况,使用lambda函数进行信息打印,客户端与服务器端连接成功之后走,会产生connected信号:
connect(tcpSocket, &QTcpSocket::connected,
[=]()
{
ui->textEditRead->setText("successful Link!");
} );
当send按钮按下时,将数据进行发送,发送的方式与服务器端的处理方式类似:
void ClientWidget::on_buttonSend_clicked()
{
//获取编辑框内容,内容转换为字符串形式
QString str = ui->textEditWrite->toPlainText();
//发送数据,首先将数据转换为utf8格式,然后通过data函数将数据转换为char *格式
tcpSocket->write( str.toUtf8().data() );
}
当服务器端发送数据给客户端时,客户端会产生一个readyRead信号,该信号会触发数据读取操作:
connect(tcpSocket, &QTcpSocket::readyRead,
[=]()
{
//获取对方发送的内容
QByteArray array = tcpSocket->readAll();
//追加到编辑区中
ui->textEditRead->append(array);
});
当客户端想要与服务器端断开连接时,首先是通过通信套接字通信套接字断开与服务器端的连接,然后将通信套接字关闭:
void ClientWidget::on_buttonClose_clicked()
{
//主动和对方断开连接
tcpSocket->disconnectFromHost();
tcpSocket->close();
}
程序整体:
.pro函数:
#------------------------------------------------- # # Project created by QtCreator 2020-01-30T23:13:39 # #------------------------------------------------- QT += core gui network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = 01_TCP TEMPLATE = app # The following define makes your compiler emit warnings if you use # any feature of Qt which as been marked as deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += main.cpp\ clientwidget.cpp HEADERS +=clientwidget.h FORMS += clientwidget.ui CONFIG +=C++11 //Lambda
clientwidget.h:
#ifndef CLIENTWIDGET_H #define CLIENTWIDGET_H #include <QWidget> #include <QTcpSocket> //通信套接字 namespace Ui { class ClientWidget; } class ClientWidget : public QWidget { Q_OBJECT public: explicit ClientWidget(QWidget *parent = 0); ~ClientWidget(); private slots: void on_buttonConnect_clicked(); void on_buttonSend_clicked(); void on_buttonClose_clicked(); private: Ui::ClientWidget *ui; QTcpSocket *tcpSocket; //通信套接字 }; #endif // CLIENTWIDGET_H
clientwidget.cpp:
#include "ui_clientwidget.h" #include "clientwidget.h" #include <QHostAddress> #include <QTcpSocket> //通信套接字 ClientWidget::ClientWidget(QWidget *parent) : QWidget(parent), ui(new Ui::ClientWidget) { ui->setupUi(this); tcpSocket = NULL; //分配空间,指定父对象 tcpSocket = new QTcpSocket(this); setWindowTitle("CLIENT"); connect(tcpSocket, &QTcpSocket::connected, [=]() { ui->textEditRead->setText("successful Link!"); } ); connect(tcpSocket, &QTcpSocket::readyRead, [=]() { //获取对方发送的内容 QByteArray array = tcpSocket->readAll(); //追加到编辑区中 ui->textEditRead->append(array); } ); } ClientWidget::~ClientWidget() { delete ui; } void ClientWidget::on_buttonConnect_clicked() { //获取服务器ip和端口 QString ip = ui->lineEditIP->text(); qint16 port = ui->lineEditPort->text().toInt(); //主动和服务器建立连接 tcpSocket->connectToHost(QHostAddress(ip), port); } void ClientWidget::on_buttonSend_clicked() { //获取编辑框内容,内容转换为字符串形式 QString str = ui->textEditWrite->toPlainText(); //发送数据,首先将数据转换为utf8格式,然后通过data函数将数据转换为char *格式 tcpSocket->write( str.toUtf8().data() ); } void ClientWidget::on_buttonClose_clicked() { //主动和对方断开连接 tcpSocket->disconnectFromHost(); tcpSocket->close(); }
运行结果: