QT5实现简单的TCP通信

QT5实现简单的TCP通信

瑟寒凌风 2018-10-23 10:05:25 9282 收藏 56

分类专栏: QT开发

原文https://blog.csdn.net/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()信号,因此为该信号添加槽函数以读取数据

 
  1. QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);

  2.  
  3. void MainWindow::socket_Read_Data()

  4. {

  5. QByteArray buffer;

  6. //读取缓冲区数据

  7. buffer = socket->readAll();

  8. }

(5)断开与服务器的连接(关于close()和disconnectFromHost()的区别,可以按F1看帮助)

socket->disconnectFromHost();

2、以下是客户端的例程

首先是mainwindow.h文件:

 
  1. //mainwindow.h

  2. #ifndef MAINWINDOW_H

  3. #define MAINWINDOW_H

  4.  
  5. #include <QMainWindow>

  6. #include <QTcpSocket>

  7.  
  8. namespace Ui {

  9. class MainWindow;

  10. }

  11.  
  12. class MainWindow : public QMainWindow

  13. {

  14. Q_OBJECT

  15.  
  16. public:

  17. explicit MainWindow(QWidget *parent = 0);

  18. ~MainWindow();

  19.  
  20. private slots:

  21.  
  22. void on_pushButton_Connect_clicked();

  23.  
  24. void on_pushButton_Send_clicked();

  25.  
  26. void socket_Read_Data();

  27.  
  28. void socket_Disconnected();

  29.  
  30. private:

  31. Ui::MainWindow *ui;

  32. QTcpSocket *socket;

  33. };

  34.  
  35. #endif // MAINWINDOW_H

然后是mainwindow.cpp文件:

 
  1. //mainwindow.cpp

  2. #include "mainwindow.h"

  3. #include "ui_mainwindow.h"

  4.  
  5. MainWindow::MainWindow(QWidget *parent) :

  6. QMainWindow(parent),

  7. ui(new Ui::MainWindow)

  8. {

  9. ui->setupUi(this);

  10.  
  11. socket = new QTcpSocket();

  12.  
  13. //连接信号槽

  14. QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);

  15. QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);

  16.  
  17. ui->pushButton_Send->setEnabled(false);

  18. ui->lineEdit_IP->setText("127.0.0.1");

  19. ui->lineEdit_Port->setText("8765");

  20.  
  21. }

  22.  
  23. MainWindow::~MainWindow()

  24. {

  25. delete this->socket;

  26. delete ui;

  27. }

  28.  
  29. void MainWindow::on_pushButton_Connect_clicked()

  30. {

  31. if(ui->pushButton_Connect->text() == tr("连接"))

  32. {

  33. QString IP;

  34. int port;

  35.  
  36. //获取IP地址

  37. IP = ui->lineEdit_IP->text();

  38. //获取端口号

  39. port = ui->lineEdit_Port->text().toInt();

  40.  
  41. //取消已有的连接

  42. socket->abort();

  43. //连接服务器

  44. socket->connectToHost(IP, port);

  45.  
  46. //等待连接成功

  47. if(!socket->waitForConnected(30000))

  48. {

  49. qDebug() << "Connection failed!";

  50. return;

  51. }

  52. qDebug() << "Connect successfully!";

  53.  
  54. //发送按键使能

  55. ui->pushButton_Send->setEnabled(true);

  56. //修改按键文字

  57. ui->pushButton_Connect->setText("断开连接");

  58. }

  59. else

  60. {

  61. //断开连接

  62. socket->disconnectFromHost();

  63. //修改按键文字

  64. ui->pushButton_Connect->setText("连接");

  65. ui->pushButton_Send->setEnabled(false);

  66. }

  67. }

  68.  
  69. void MainWindow::on_pushButton_Send_clicked()

  70. {

  71. qDebug() << "Send: " << ui->textEdit_Send->toPlainText();

  72. //获取文本框内容并以ASCII码形式发送

  73. socket->write(ui->textEdit_Send->toPlainText().toLatin1());

  74. socket->flush();

  75. }

  76.  
  77. void MainWindow::socket_Read_Data()

  78. {

  79. QByteArray buffer;

  80. //读取缓冲区数据

  81. buffer = socket->readAll();

  82. if(!buffer.isEmpty())

  83. {

  84. QString str = ui->textEdit_Recv->toPlainText();

  85. str+=tr(buffer);

  86. //刷新显示

  87. ui->textEdit_Recv->setText(str);

  88. }

  89. }

  90.  
  91. void MainWindow::socket_Disconnected()

  92. {

  93. //发送按键失能

  94. ui->pushButton_Send->setEnabled(false);

  95. //修改按键文字

  96. ui->pushButton_Connect->setText("连接");

  97. qDebug() << "Disconnected!";

  98. }

最后是ui的设计:

 

二、服务器编写

 

1、服务器除了使用到了QTcpSocket类,还需要用到QTcpSever类。即便如此,也只是比客户端复杂一点点,用到了6个步骤:

(1)创建QTcpSever对象

server = new QTcpServer();

 (2)侦听一个端口,使得客户端可以使用这个端口访问服务器

server->listen(QHostAddress::Any, port)

(3)当服务器被客户端访问时,会发出newConnection()信号,因此为该信号添加槽函数,并用一个QTcpSocket对象接受客户端访问

 
  1. connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect);

  2.  
  3. void MainWindow::server_New_Connect()

  4. {

  5. //获取客户端连接

  6. socket = server->nextPendingConnection();

  7. }

(4)使用socket的write函数向客户端发送数据

socket->write(data);

(5)当socket接收缓冲区有新数据到来时,会发出readRead()信号,因此为该信号添加槽函数以读取数据

 
  1. QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);

  2.  
  3. void MainWindow::socket_Read_Data()

  4. {

  5. QByteArray buffer;

  6. //读取缓冲区数据

  7. buffer = socket->readAll();

  8. }

(6)取消侦听

server->close();

2、以下是服务器的例程

首先是mainwindow.h文件:

 
  1. //mainwindow.h

  2. #ifndef MAINWINDOW_H

  3. #define MAINWINDOW_H

  4.  
  5. #include <QMainWindow>

  6. #include <QTcpServer>

  7. #include <QTcpSocket>

  8.  
  9. namespace Ui {

  10. class MainWindow;

  11. }

  12.  
  13. class MainWindow : public QMainWindow

  14. {

  15. Q_OBJECT

  16.  
  17. public:

  18. explicit MainWindow(QWidget *parent = 0);

  19. ~MainWindow();

  20.  
  21. private slots:

  22. void on_pushButton_Listen_clicked();

  23.  
  24. void on_pushButton_Send_clicked();

  25.  
  26. void server_New_Connect();

  27.  
  28. void socket_Read_Data();

  29.  
  30. void socket_Disconnected();

  31.  
  32. private:

  33. Ui::MainWindow *ui;

  34. QTcpServer* server;

  35. QTcpSocket* socket;

  36. };

  37.  
  38. #endif // MAINWINDOW_H

然后是mainwindow.cpp文件:

 
  1. #include "mainwindow.h"

  2. #include "ui_mainwindow.h"

  3.  
  4. MainWindow::MainWindow(QWidget *parent) :

  5. QMainWindow(parent),

  6. ui(new Ui::MainWindow)

  7. {

  8. ui->setupUi(this);

  9.  
  10. ui->lineEdit_Port->setText("8765");

  11. ui->pushButton_Send->setEnabled(false);

  12.  
  13. server = new QTcpServer();

  14.  
  15. //连接信号槽

  16. connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect);

  17. }

  18.  
  19. MainWindow::~MainWindow()

  20. {

  21. server->close();

  22. server->deleteLater();

  23. delete ui;

  24. }

  25.  
  26. void MainWindow::on_pushButton_Listen_clicked()

  27. {

  28. if(ui->pushButton_Listen->text() == tr("侦听"))

  29. {

  30. //从输入框获取端口号

  31. int port = ui->lineEdit_Port->text().toInt();

  32.  
  33. //监听指定的端口

  34. if(!server->listen(QHostAddress::Any, port))

  35. {

  36. //若出错,则输出错误信息

  37. qDebug()<<server->errorString();

  38. return;

  39. }

  40. //修改按键文字

  41. ui->pushButton_Listen->setText("取消侦听");

  42. qDebug()<< "Listen succeessfully!";

  43. }

  44. else

  45. {

  46. /*

  47. //如果正在连接(点击侦听后立即取消侦听,若socket没有指定对象会有异常,应修正——2017.9.30)

  48. if(socket->state() == QAbstractSocket::ConnectedState)

  49. {

  50. //关闭连接

  51. socket->disconnectFromHost();

  52. }

  53. */

  54. socket->abort();

  55. //取消侦听

  56. server->close();

  57. //修改按键文字

  58. ui->pushButton_Listen->setText("侦听");

  59. //发送按键失能

  60. ui->pushButton_Send->setEnabled(false);

  61. }

  62.  
  63. }

  64.  
  65. void MainWindow::on_pushButton_Send_clicked()

  66. {

  67. qDebug() << "Send: " << ui->textEdit_Send->toPlainText();

  68. //获取文本框内容并以ASCII码形式发送

  69. socket->write(ui->textEdit_Send->toPlainText().toLatin1());

  70. socket->flush();

  71. }

  72.  
  73. void MainWindow::server_New_Connect()

  74. {

  75. //获取客户端连接

  76. socket = server->nextPendingConnection();

  77. //连接QTcpSocket的信号槽,以读取新数据

  78. QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);

  79. QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);

  80. //发送按键使能

  81. ui->pushButton_Send->setEnabled(true);

  82.  
  83. qDebug() << "A Client connect!";

  84. }

  85.  
  86. void MainWindow::socket_Read_Data()

  87. {

  88. QByteArray buffer;

  89. //读取缓冲区数据

  90. buffer = socket->readAll();

  91. if(!buffer.isEmpty())

  92. {

  93. QString str = ui->textEdit_Recv->toPlainText();

  94. str+=tr(buffer);

  95. //刷新显示

  96. ui->textEdit_Recv->setText(str);

  97. }

  98. }

  99.  
  100. void MainWindow::socket_Disconnected()

  101. {

  102. //发送按键失能

  103. ui->pushButton_Send->setEnabled(false);

  104. qDebug() << "Disconnected!";

  105. }

最后是ui的设计:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值