当前位置:   article > 正文

QT:Socket通讯(TCP) 学习笔记_qtcpsocket

qtcpsocket

环境:Qt Creator 5.9,7 

目录

1. 准备工作

2.服务器端 server项目

2.1  ui设计界面

2.2  .h文件代码

2.3  .cpp文件代码

3. 客户端 client项目

3.1  ui设计界面

3.2  .h文件代码

3.3  .cpp文件代码 

4. 测试演示

5.补充笔记


TCP服务端:
第一步:
创建监听套接字的QTcpSever

第二步:listen------监听是否有新的连接进来

第三步:取出套接字

第四步:读取套接字的内容


TCP客户端:
第一步:
创建套接字,与服务端的IP地址和端口号连接.(注:这里的端口号和上面服务端绑定的那个端口号是一样的,别搞错了.)

第二步:连接成功后就可以直接向服务端发消息了.

若要多次向服务端发消息,可以while循环或者是其他.在这里要注意如果要多次发消息的话,waitForBytesWritten()这个函数是必不可少的,不然多次的话可能通信会失败.

注:write()函数和被触发的读的readyRead()信号并不是一一对应的,比如可能你客户端write了三次,服务端那边的readyRead可能才被触发一次.

1. 准备工作

需创建两个project,一个服务器端 server,一个客户端 client。

服务器端 server: 

客户端 client:

注意: .pro文件记得添加

	QT       += network   //引用头文件 TcpServer 和 TcpSocket 的前提

 

2.服务器端 server项目

2.1  ui设计界面

2.2  .h文件代码

  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3. #include <QMainWindow>
  4. #include <QTcpServer>
  5. #include <QTcpSocket>
  6. #include <QString>
  7. namespace Ui {
  8. class MainWindow;
  9. }
  10. class MainWindow : public QMainWindow
  11. {
  12. Q_OBJECT
  13. public:
  14. explicit MainWindow(QWidget *parent = nullptr);
  15. ~MainWindow();
  16. QTcpServer *tcpserver; //第一步:创建监听套接字的QTcpSever
  17. QTcpSocket *tcpsocket;
  18. private slots:
  19. void on_connectbt_clicked();
  20. void newConnection_Slot();
  21. void readyRead_Slot();
  22. void on_disconnectbt_clicked();
  23. void on_sendbt_clicked();
  24. private:
  25. Ui::MainWindow *ui;
  26. };
  27. #endif // MAINWINDOW_H

2.3  .cpp文件代码

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. MainWindow::MainWindow(QWidget *parent) :
  4. QMainWindow(parent),
  5. ui(new Ui::MainWindow)
  6. {
  7. ui->setupUi(this);
  8. tcpserver=new QTcpServer(this);
  9. tcpsocket=new QTcpSocket(this);
  10. //若有新的客户端连接的话,会触发信号newConnection_Slot()
  11. connect(tcpserver,SIGNAL(newConnection()),this,SLOT(newConnection_Slot()));
  12. }
  13. void MainWindow::newConnection_Slot()
  14. {
  15. //第三步:取出套接字
  16. tcpsocket=tcpserver->nextPendingConnection(); //获取已经连接的客户端的SOCKET套接字
  17. connect(tcpsocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));//若客户端有消息进来的话,会触发信号readyRead_Slot();
  18. //获取对方的IP和端口
  19. QString sIp = tcpsocket->peerAddress().toString();
  20. quint16 sPort = tcpsocket->peerPort();
  21. qDebug() << sIp << sPort;
  22. //connect(tcpsocket, SIGNAL(disconnected()), this, SLOT(slotServerDisConnection()));//断开连接的话会触发disconnected();
  23. }
  24. void MainWindow::readyRead_Slot()
  25. {
  26. //第四步:读取套接字的内容
  27. //从socket中读出数据
  28. QString buf;
  29. buf=tcpsocket->readAll();
  30. ui->receivewd->appendPlainText(buf);
  31. /*或
  32. QByteArray baArray = tcpsocket->readAll();
  33. QString sMsg = baArray;
  34. ui->receivewd->appendPlainText(receivewd);
  35. */
  36. }
  37. MainWindow::~MainWindow()
  38. {
  39. delete ui;
  40. }
  41. void MainWindow::on_connectbt_clicked()//连接服务器
  42. {
  43. //第二部步:listen------监听是否有新的连接进来
  44. tcpserver->listen(QHostAddress::Any,ui->portnum->text().toUInt());//监听端口号
  45. }
  46. void MainWindow::on_disconnectbt_clicked()//关闭服务器
  47. {
  48. tcpserver->close();
  49. }
  50. void MainWindow::on_sendbt_clicked()//发送信息
  51. {
  52. // toLatin1()
  53. // tcpsocket->write(ui->sendwd->text().toLatin1());
  54. // tcpsocket->write(ui->sendwd->text().toLocal8Bit(),ui->sendwd->text().length());
  55. tcpsocket->write(ui->sendwd->text().toLocal8Bit().data());
  56. }

3. 客户端 client项目

3.1  ui设计界面

3.2  .h文件代码

  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3. #include <QMainWindow>
  4. //#include <QTcpServer>
  5. #include <QTcpSocket>//服务端只用socket
  6. namespace Ui {
  7. class MainWindow;
  8. }
  9. class MainWindow : public QMainWindow
  10. {
  11. Q_OBJECT
  12. public:
  13. explicit MainWindow(QWidget *parent = nullptr);
  14. ~MainWindow();
  15. QTcpSocket *tcpsocket;
  16. private slots:
  17. void on_openclient_clicked();
  18. void connected_SLOT();
  19. void readyRead_Slot();
  20. void on_closeclient_clicked();
  21. void on_sent_clicked();
  22. private:
  23. Ui::MainWindow *ui;
  24. };
  25. #endif // MAINWINDOW_H

3.3  .cpp文件代码 

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. #include "QString"
  4. #include "stdio.h"
  5. //#pragma execution_character_set("utf-8")
  6. MainWindow::MainWindow(QWidget *parent) :
  7. QMainWindow(parent),
  8. ui(new Ui::MainWindow)
  9. {
  10. ui->setupUi(this);
  11. tcpsocket=new QTcpSocket(this);
  12. }
  13. MainWindow::~MainWindow()
  14. {
  15. delete ui;
  16. }
  17. void MainWindow::connected_SLOT()
  18. {
  19. QObject::connect(tcpsocket, &QTcpSocket::readyRead, this, &MainWindow::readyRead_Slot);
  20. // connect(tcpsocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));//将信号连接到槽,书写比较明确
  21. }
  22. void MainWindow::readyRead_Slot()//定义接收信号的槽
  23. {
  24. QString buf;
  25. buf=tcpsocket->readAll();
  26. ui->receivewd->appendPlainText(buf);//接收由tcp发送过来的信息
  27. // ui->receivewd->appendPlainText(buf.toUtf8());//接收由tcp发送过来的信息
  28. }
  29. void MainWindow::on_openclient_clicked()
  30. {
  31. //第一步:创建套接字,与服务端的IP地址和端口号连接.
  32. //注:这里的端口号和上面服务端绑定的那个端口号是一样的,别搞错了.
  33. //连接服务端
  34. tcpsocket->connectToHost(ui->ipnum->text(),ui->portnum->text().toInt());//转为无符号,连接服务器端口
  35. connect(tcpsocket,SIGNAL(connected()),this,SLOT(connected_SLOT()));
  36. printf("打开客户端 ");
  37. /*
  38. //成功连接返回true,错误返回false
  39. if(m_tsTcpSocket->waitForConnected())
  40. {
  41. qDebug() << "connect success";
  42. }
  43. */
  44. }
  45. void MainWindow::on_closeclient_clicked()
  46. {
  47. tcpsocket->close();
  48. printf("关闭客户端 ");
  49. }
  50. void MainWindow::on_sent_clicked()
  51. {
  52. tcpsocket->write(ui->sendwd->text().toLocal8Bit().data(),ui->sendwd->text().length());//丽丽
  53. //tcpsocket->write(ui->sendwd->text().toLocal8Bit().data());//网上
  54. //tcpsocket->write(ui->sendwd->toPlainText().toLatin1());//xie宏伟
  55. /*
  56. QString str;
  57. int iSize = tcpsocket->write(str.toUtf8().data());//返回字节的大小
  58. //等待write写完再写下一次的write
  59. if(!tcpsocket->waitForBytesWritten(50000))
  60. {
  61. return;
  62. }
  63. if(iSize ==-1) //判断发送是否成功
  64. {
  65. qDebug() << "write error";
  66. return;
  67. }
  68. 若要多次向服务端发消息,可以while循环或者是其他.在这里要注意如果要多次发消息的
  69. 话,waitForBytesWritten()这个函数是必不可少的,不然多次的话可能通信会失败.
  70. 注:write()函数和被触发的读的readyRead()信号并不是一一对应的,比如可能你客户端
  71. write了三次,服务端那边的readyRead可能才被触发一次.
  72. */
  73. }

主函数代码(两个工程皆相同):

  1. #include "mainwindow.h"
  2. #include <QApplication>
  3. //#include <QtNetwork>
  4. int main(int argc, char *argv[])
  5. {
  6. QApplication a(argc, argv);
  7. MainWindow w;
  8. w.show();
  9. return a.exec();
  10. }

 补充:客户端主动断开服务的连接

  1. void TcpClient::disConnectSever()
  2. {
  3. //方式一
  4. m_tcpSocket->flush();
  5. m_tcpSocket->disconnectFromHost();
  6. //方式二
  7. m_tcpSocket->abort();
  8. }

注:方式二abort与方式一的区别:abort中止当前连接并重置套接字。与disConnectFromHost()不同,该函数会立即关闭套接字,丢弃写缓冲区中的所有挂起数据。 

4. 测试演示

注意:

端口号须一致(端口号相当于房间号,进入同一房间后才可进行通讯)

服务器端须先点击 “ 连接服务器 ” 

客户端须先点击 “ 打开客户端 ” 

其次两者皆是输入内容再点击 “ 发送 ” 按钮

即可实现两者间的通讯

(暂不支持发送中文)

5.补充笔记

connect 函数:

connect(Sender,SIGNAL(signal),Receiver,SLOT(slot));  // 按键单击信号连接到按键槽函数

函数4个参数:发射信号的对象,发射的信号,接受信号的对象,要执行的槽;

详情:(3条消息) QT connect()连接函数_心若十年的博客-CSDN博客_qt connect()

(以上学习笔记参考了(3条消息) qt中socket编程_真爱是蓝色的博客-CSDN博客_qt socket

QT TCP简单的通信示例

拓展:

串口通信参考链接:QT三驾马车(一)——实现上位机(串口数据发送和接收)_qt上位机-CSDN博客

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/1016705
推荐阅读
相关标签
  

闽ICP备14008679号