Qt的TCP通信 您所在的位置:网站首页 qt创建udp连接 Qt的TCP通信

Qt的TCP通信

2023-07-03 06:33| 来源: 网络整理| 查看: 265

Qt的TCP通信—客户端的实现

客户端程序TCPClient只需要使用一个QTcpSocket对象,就可以和服务端程序TCPServer进行通信

服务端的实现流程

客户端的QTcpSocket首先通过connectToHost()尝试连接到服务器,需要指定服务器的IP地址和端口,connectToHost()是异步方式连接到服务器,不会阻塞程序运行,连接后发射connected()信号。

与服务器端建立socket连接后,就可以向缓冲区写数据或从接收缓冲区读取数据,实现数据的通信。当缓冲区有数据进入时,回发射readyRead()信号,一般在此信号的槽函数里读取缓冲区数据。

QTcpSocket是从QIODevice间接继承的,所以可以使用流数据读写功能。一个QTcpSocket既可以接收数据也可以发送数据,而且接收与发送是异步工作的,有各自的缓冲区。

客户端程序运行界面如图所示

在这里插入图片描述

实现功能:

​ 1、通过IP地址和端口号连接到服务器

​ 2、采用基于行的数据通信协议,于服务端收发数据

​ 3、处理QTcpSocket的StateChange()信号,在状态栏显示socket的状态

TCP客户端代码实现

mainwindow.h的实现

#ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT private: QTcpSocket *tcpClient; //socket QLabel *LabSocketState; //状态栏显示标签 QString getLocalIP();//获取本机IP地址 protected: void closeEvent(QCloseEvent *event); public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: //自定义槽函数 void onConnected(); void onDisconnected(); void onSocketStateChange(QAbstractSocket::SocketState socketState); void onSocketReadyRead();//读取socket传入的数据 void on_actConnect_triggered(); void on_actDisconnect_triggered(); void on_actClear_triggered(); void on_btnSend_clicked(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H

mainwindow.cpp的实现

#include "mainwindow.h" #include "ui_mainwindow.h" #include #include QString MainWindow::getLocalIP() { QString hostName=QHostInfo::localHostName();//本地主机名 QHostInfo hostInfo=QHostInfo::fromName(hostName); QString localIP=""; QList addList=hostInfo.addresses();// if (!addList.isEmpty()) for (int i=0;istate()==QAbstractSocket::ConnectedState) tcpClient->disconnectFromHost(); event->accept(); } MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); tcpClient=new QTcpSocket(this); //创建socket变量 LabSocketState=new QLabel("Socket状态:");//状态栏标签 LabSocketState->setMinimumWidth(250); ui->statusBar->addWidget(LabSocketState); QString localIP=getLocalIP();//本机IP this->setWindowTitle(this->windowTitle()+"----本机IP:"+localIP); ui->comboServer->addItem(localIP); connect(tcpClient,SIGNAL(connected()),this,SLOT(onConnected())); connect(tcpClient,SIGNAL(disconnected()),this,SLOT(onDisconnected())); //获取连接状态 connect(tcpClient,SIGNAL(stateChanged(QAbstractSocket::SocketState)), this,SLOT(onSocketStateChange(QAbstractSocket::SocketState))); connect(tcpClient,SIGNAL(readyRead()), this,SLOT(onSocketReadyRead())); } MainWindow::~MainWindow() { delete ui; } void MainWindow::onConnected() { //connected()信号槽函数 ui->plainTextEdit->appendPlainText("**已连接到服务器"); ui->plainTextEdit->appendPlainText("**peer address:"+ tcpClient->peerAddress().toString()); ui->plainTextEdit->appendPlainText("**peer port:"+ QString::number(tcpClient->peerPort())); ui->actConnect->setEnabled(false); ui->actDisconnect->setEnabled(true); } void MainWindow::onDisconnected() {//disConnected()信号槽函数 ui->plainTextEdit->appendPlainText("**已断开与服务器的连接"); ui->actConnect->setEnabled(true); ui->actDisconnect->setEnabled(false); } void MainWindow::onSocketReadyRead() {//readyRead()信号槽函数 while(tcpClient->canReadLine()) ui->plainTextEdit->appendPlainText("[in] "+tcpClient->readLine()); } void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState) {//stateChange()信号槽函数 switch(socketState) { case QAbstractSocket::UnconnectedState: LabSocketState->setText("scoket状态:UnconnectedState"); break; case QAbstractSocket::HostLookupState: LabSocketState->setText("scoket状态:HostLookupState"); break; case QAbstractSocket::ConnectingState: LabSocketState->setText("scoket状态:ConnectingState"); break; case QAbstractSocket::ConnectedState: LabSocketState->setText("scoket状态:ConnectedState"); break; case QAbstractSocket::BoundState: LabSocketState->setText("scoket状态:BoundState"); break; case QAbstractSocket::ClosingState: LabSocketState->setText("scoket状态:ClosingState"); break; case QAbstractSocket::ListeningState: LabSocketState->setText("scoket状态:ListeningState"); } } void MainWindow::on_actConnect_triggered() {//连接到服务器 QString addr=ui->comboServer->currentText(); quint16 port=ui->spinPort->value(); tcpClient->connectToHost(addr,port); // tcpClient->connectToHost(QHostAddress::LocalHost,port); } void MainWindow::on_actDisconnect_triggered() {//断开与服务器的连接 if (tcpClient->state()==QAbstractSocket::ConnectedState) tcpClient->disconnectFromHost(); } void MainWindow::on_actClear_triggered() { ui->plainTextEdit->clear(); } void MainWindow::on_btnSend_clicked() {//发送数据 QString msg=ui->editMsg->text(); ui->plainTextEdit->appendPlainText("[out] "+msg); ui->editMsg->clear(); ui->editMsg->setFocus(); QByteArray str=msg.toUtf8(); str.append('\n'); tcpClient->write(str); } 程序运行结果如图所示

在这里插入图片描述

总结

服务器和客户端的实现只是简单的演示了TCP通信的基本原理,TCPServer只允许一个TCPClient客户端接入。而一般的TCP服务器程序允许多个客户端接入。为了使每个socket连接独立通信不影响,一般采用多线程,既为一个socket连接创建一个线程

lient->write(str); }

#### 程序运行结果如图所示 [外链图片转存中...(img-ldEvMlvq-1687778801285)] ### 总结 服务器和客户端的实现只是简单的演示了TCP通信的基本原理,TCPServer只允许一个TCPClient客户端接入。而一般的TCP服务器程序允许多个客户端接入。为了使每个socket连接独立通信不影响,一般采用多线程,既为一个socket连接创建一个线程 以上实例之间的数据通信采用基于行的数据通信协议,只能传输字符串数据。QTcpSocket间接继承QIODevice,可以使用数据流的方式传输二进制数据流,列如传输图片、任意格式文件等。但是这涉及到服务端和客户端之间通信协议的定义。


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有