• 6.19作业


    网络聊天室服务器实现 

    1. //头文件
    2. #ifndef WIDGET_H
    3. #define WIDGET_H
    4. #include
    5. #include //服务器端类
    6. #include //消息对话框类
    7. #include //客户端类
    8. #include //链表容器类
    9. QT_BEGIN_NAMESPACE
    10. namespace Ui { class Widget; }
    11. QT_END_NAMESPACE
    12. class Widget : public QWidget
    13. {
    14. Q_OBJECT
    15. public:
    16. Widget(QWidget *parent = nullptr);
    17. ~Widget();
    18. private slots:
    19. void on_startbtn_clicked();
    20. public slots:
    21. void newConnection_slot();
    22. void readyRead_slot();
    23. private:
    24. Ui::Widget *ui;
    25. //实例化一个服务器指针
    26. QTcpServer *server;
    27. //定义一个存放客户端套接字的容器
    28. QList socketList;
    29. };
    30. #endif // WIDGET_H
    31. //源文件
    32. #include "widget.h"
    33. #include "ui_widget.h"
    34. Widget::Widget(QWidget *parent)
    35. : QWidget(parent)
    36. , ui(new Ui::Widget)
    37. , server(new QTcpServer(this))//给服务器指针实例化空间
    38. {
    39. ui->setupUi(this);
    40. }
    41. Widget::~Widget()
    42. {
    43. delete ui;
    44. }
    45. //启动按钮对应的槽函数
    46. void Widget::on_startbtn_clicked()
    47. {
    48. //获取ui界面上的端口号
    49. quint16 port = ui->PortEdit->text().toUInt();//将字符串转换成整型
    50. //让服务器设置监听
    51. if(server->listen(QHostAddress::Any,port))
    52. {
    53. QMessageBox::information(this,"","启动服务器成功!");
    54. }
    55. else
    56. {
    57. QMessageBox::information(this,"","启动服务器失败!");
    58. return;
    59. }
    60. //此时服务器已设置好监听,如果有客户端发来连接请求,那么服务器端就会自动发射一个newConnection()信号
    61. //将该信号连接到自定义的槽函数中,处理逻辑代码
    62. connect(server,&QTcpServer::newConnection,this,&Widget::newConnection_slot);
    63. }
    64. //newConnection_slot信号对应的槽函数实现
    65. void Widget::newConnection_slot()
    66. {
    67. //使用nextpaddingConnection获取最新连接客户端的套接字
    68. //函数原型:virtual QTcpSocket *nextPendingConnection();
    69. QTcpSocket *s = server->nextPendingConnection();
    70. //将客户端放入容器中
    71. socketList.push_back(s);
    72. //程序运行至此说明服务器和客户端已经建立了连接
    73. //如果有客户端向服务器发来数据,则客户端就会自动发射一个readyRead信号,
    74. //就可以将该信号连接到自定义的槽函数中,读取数据
    75. connect(s,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);
    76. }
    77. void Widget::readyRead_slot()
    78. {
    79. //遍历客户端容器,移除无效客户端
    80. for(int i=0; icount(); i++)//count为容器的元素个数
    81. {
    82. //state函数判断连接状态
    83. //函数原型:SocketState state() const;
    84. //函数返回值,枚举值为0的表示未连接
    85. if(socketList.at(i)->state() == 0)
    86. {
    87. //删除该元素
    88. socketList.removeAt(i);
    89. }
    90. }
    91. //遍历客户端容器寻找哪个客户端有数据待读
    92. for(int i=0; icount(); i++)
    93. {
    94. //函数功能:数据的字节
    95. //函数原型:qint64 bytesAvailable() const override;
    96. if(socketList.at(i)->bytesAvailable()!=0)
    97. {
    98. QByteArray msg = socketList.at(i)->readAll();
    99. //将读取到的数据放入ui界面上
    100. ui->listWidget->addItem(QString::fromLocal8Bit(msg));
    101. //将数据广播给所有客户端
    102. for(int j=0; jcount(); j++)
    103. {
    104. socketList.at(j)->write(msg);
    105. }
    106. }
    107. }
    108. }

  • 相关阅读:
    C/C+=内存管理
    QT小记:The QColor ctor taking ints is cheaper than the one taking string literals
    初探Java 注解处理器 (Annotation Processor)
    我给 Apache 顶级项目提了个 Bug
    利用C++开发一个迷你的英文单词录入和测试小程序-升级版本
    Nginx学习笔记09——URLRewrite伪静态
    JAVA中类和对象的认识
    CAD Exchanger SDK 3.23.0 的亮点
    【分布式应用】消息队列之卡夫卡 + EFLFK集群部署
    二、sql手工注入
  • 原文地址:https://blog.csdn.net/weixin_61168786/article/details/139812585