当前位置:   article > 正文

Qt creator day5练习

Qt creator day5练习

Qt 中实现TCP 聊天服务器

大致流程

创建套接字服务器QTcpServer对象

通过QTcpServer对象设置监听,即QTcpServer::listen()

基于QTcpServer::newConnection()信号检测是否有新的客户端连接

如果有新的客户端连接 调用QTcpSocket *QTcpServer::nextPendingConnection()得到通信的套接字对象

使用通信的套接字对象QTcpSocket和客户端进行通信

.pro文件

  1. QT += core gui network # 所需模块network 添加后记得构建
  2. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
  3. CONFIG += c++11
  4. # The following define makes your compiler emit warnings if you use
  5. # any Qt feature that has been marked deprecated (the exact warnings
  6. # depend on your compiler). Please consult the documentation of the
  7. # deprecated API in order to know how to port your code away from it.
  8. DEFINES += QT_DEPRECATED_WARNINGS
  9. # You can also make your code fail to compile if it uses deprecated APIs.
  10. # In order to do so, uncomment the following line.
  11. # You can also select to disable deprecated APIs only up to a certain version of Qt.
  12. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
  13. SOURCES += \
  14. main.cpp \
  15. widget.cpp
  16. HEADERS += \
  17. widget.h
  18. FORMS += \
  19. widget.ui
  20. # Default rules for deployment.
  21. qnx: target.path = /tmp/$${TARGET}/bin
  22. else: unix:!android: target.path = /opt/$${TARGET}/bin
  23. !isEmpty(target.path): INSTALLS += target

.h文件

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. #include <QTcpServer> //??包含TCP服务器类
  5. #include <QMessageBox> //消息对话框类
  6. #include <QTcpSocket> //包含客户端类
  7. QT_BEGIN_NAMESPACE
  8. namespace Ui { class Widget; }
  9. QT_END_NAMESPACE
  10. class Widget : public QWidget
  11. {
  12. Q_OBJECT
  13. public:
  14. Widget(QWidget *parent = nullptr);
  15. ~Widget();
  16. private slots:
  17. void on_startBtn_clicked();
  18. void newConnection_slot(); //声明一下服务器检测到新的客户端连接时,发射出来的信号到这个槽函数
  19. void readyRead_slot(); //声明一下客户端发射的readyRead()信号对应的槽函数
  20. private:
  21. Ui::Widget *ui;
  22. QTcpServer *server; //创建一个套接字服务器QTcpServer对象 在构造函数初始化列表中初始化
  23. QList<QTcpSocket *> socketList; //定义一个存放客户套接字的容器
  24. };
  25. #endif // WIDGET_H

main.cpp

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

.cpp文件

  1. #include "widget.h"
  2. #include "ui_widget.h"
  3. Widget::Widget(QWidget *parent)
  4. : QWidget(parent)
  5. , ui(new Ui::Widget)
  6. ,server(new QTcpServer(this)) //初始化列表 初始化server
  7. {
  8. ui->setupUi(this);
  9. }
  10. Widget::~Widget()
  11. {
  12. delete ui;
  13. }
  14. void Widget::on_startBtn_clicked()
  15. {
  16. //定义一个 quint16 类型的变量port 接收 字符串端口转换成 整型的端口
  17. quint16 port = ui->portEdit->text().toUInt();
  18. //调用 QTcpServer类型的对象server里的listen函数,实现监听
  19. if(server->listen(QHostAddress::Any,port))
  20. {
  21. //启动监听成功
  22. QMessageBox::information(this,"","启动服务器成功");
  23. }
  24. else
  25. {
  26. //启动监听失败
  27. QMessageBox::critical(this,"","启动服务器失败");
  28. }
  29. //此时服务器已经成功启动监听,如果有客户端发来连接,那么服务器端就会自动发射一个newConnection()的信号
  30. //将该信号连接到自定义的槽函数中
  31. connect(server,&QTcpServer::newConnection,this,&Widget::newConnection_slot);
  32. }
  33. //newConnection_slot()槽函数的实现
  34. //有客户端连接时,服务器发射一个newConnection信号后,执行这个函数
  35. void Widget::newConnection_slot()
  36. {
  37. //使用QTcpSocket *QTcpServer::nextPenddingConnection()函数得到通信的套接字对象
  38. QTcpSocket *s = server->nextPendingConnection();
  39. socketList.push_back(s); // 用尾插法将套接字放入链表
  40. //如果有客户端发来数据,客户端就会自动发射一个readyRead信号,就可以将该信号连接到自定义的槽函数中
  41. connect(s,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);
  42. }
  43. //客户端发射信号对应的槽函数的实现
  44. void Widget::readyRead_slot()
  45. {
  46. //遍历有效客户端,移除无效客户端
  47. for(int i=0; i<socketList.count(); i++)
  48. {
  49. if(socketList.at(i)->state() == 0)
  50. {
  51. socketList.removeAt(i); //删除该元素
  52. }
  53. }
  54. //再遍历客户端容器,寻找哪个客户端的数据待读
  55. for(int i=0; i<socketList.count(); i++)
  56. {
  57. if(socketList.at(i)->bytesAvailable() != 0)
  58. {
  59. //!= 0 说明这些是有效数据
  60. QByteArray msg = socketList.at(i)->readAll();
  61. //将读取到的数据 放到ui界面上
  62. ui->listWidget->addItem(QString::fromLocal8Bit(msg)); //fromlocal8bit() 将Windows的GBK字符转换为Qt的Unicode
  63. //QString::Local8bit是本地操作系统设置的字符集编码
  64. //将数据广播给所有客户端
  65. for(int i=0; i<socketList.count(); i++)
  66. {
  67. socketList.at(i)->write(msg);
  68. }
  69. }
  70. }
  71. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/744608
推荐阅读
相关标签
  

闽ICP备14008679号