• 10.4 小任务


    目录

    QT实现TCP服务器客户端搭建的代码,现象

    TCP服务器

    .h文件

    .cpp文件

    现象

    TCP客户端

    .h文件

    .cpp文件

    现象


    QT实现TCP服务器客户端搭建的代码,现象

    TCP服务器

    .h文件

    1. #ifndef WIDGET_H
    2. #define WIDGET_H
    3. #include
    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. void newConnection_slot(); //自定义处理newconnect信号的槽函数声明
    21. void readyRead_slot(); //自定义处理readyRead信号的槽函数的声明
    22. private:
    23. Ui::Widget *ui;
    24. //定义服务器指针
    25. QTcpServer *server;
    26. //定义客户端容器 是个链表
    27. QList clientList;
    28. };
    29. #endif // WIDGET_H

    .cpp文件

    1. #include "widget.h"
    2. #include "ui_widget.h"
    3. Widget::Widget(QWidget *parent)
    4. : QWidget(parent)
    5. , ui(new Ui::Widget)
    6. {
    7. ui->setupUi(this);
    8. //实例化一个服务器
    9. server =new QTcpServer(this);
    10. connect(server,&QTcpServer::newConnection,this,&Widget::newConnection_slot);
    11. }
    12. Widget::~Widget()
    13. {
    14. delete ui;
    15. }
    16. //启动服务器按钮对应的槽函数
    17. void Widget::on_startBtn_clicked()
    18. {
    19. quint16 port=ui->portEdit->text().toUInt(); //获取ui界面上的端口号
    20. //监听客户端的连接请求
    21. //bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);
    22. if(!server->listen(QHostAddress::Any,port))
    23. {
    24. QMessageBox::information(this,"失败","监听失败");
    25. return ;
    26. }else {
    27. QMessageBox::information(this,"成功","服务器启动成功");
    28. }
    29. }
    30. //自定义处理newconnect信号的槽函数的实现
    31. void Widget::newConnection_slot()
    32. {
    33. qDebug()<<"您有新的客户端发来连接请求了";
    34. //获取最新连接的客户端套接字
    35. QTcpSocket *s=server->nextPendingConnection();
    36. //将该套接字,放入客户端链表中
    37. clientList.push_back(s);
    38. connect(s,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);
    39. }
    40. //readyRead信号对应槽函数的实现
    41. void Widget::readyRead_slot()
    42. {
    43. qDebug()<<"有新的客户端消息发来了";
    44. //遍历客户端链表,将无效的客户端溢出
    45. for(int i=0;isize();i++)
    46. {
    47. //判断当前套接字是否是有效连接
    48. if(0==clientList[i]->state())
    49. {
    50. //如果是0,表示该套接字为无效连接
    51. //将该套接字移除链表
    52. clientList.removeAt(i);
    53. }
    54. }
    55. //遍历客户端链表,判断是哪个客户端发来的数据
    56. for(int i=0;isize();i++)
    57. {
    58. //函数原型
    59. if(0!=clientList[i]->bytesAvailable())
    60. {
    61. //将该套接字中的数据读取出来
    62. QByteArray msg=clientList[i]->readAll();
    63. //将数据展示到ui界面
    64. ui->msgWidget->addItem(QString::fromLocal8Bit(msg));
    65. //将接收到的数据,转发给所有客户端
    66. for(int j=0;jsize();j++)
    67. {
    68. clientList[j]->write(msg);
    69. }
    70. }
    71. }
    72. }

    现象

    TCP客户端

    .h文件

    1. #ifndef WIDGET_H
    2. #define WIDGET_H
    3. #include
    4. #include //客户端类
    5. #include
    6. QT_BEGIN_NAMESPACE
    7. namespace Ui { class Widget; }
    8. QT_END_NAMESPACE
    9. class Widget : public QWidget
    10. {
    11. Q_OBJECT
    12. public:
    13. Widget(QWidget *parent = nullptr);
    14. ~Widget();
    15. private slots:
    16. void on_connectBtn_clicked();
    17. void connected_slot(); //自定义处理connect信号的槽函数的声明
    18. void readyRead_slot(); //自定义处理readyRead信号的槽函数的声明
    19. void on_sendBtn_clicked();
    20. void on_disconnectBtn_clicked();
    21. void disconnected_slot(); //自定义处理disconnect信号的槽函数声明
    22. private:
    23. Ui::Widget *ui;
    24. //定义客户端指针
    25. QTcpSocket * socket;
    26. //定义字符串接受用户
    27. QString userName;
    28. };
    29. #endif // WIDGET_H

    .cpp文件

    1. #include "widget.h"
    2. #include "ui_widget.h"
    3. Widget::Widget(QWidget *parent)
    4. : QWidget(parent)
    5. , ui(new Ui::Widget)
    6. {
    7. ui->setupUi(this);
    8. //给客户端指针实例化对象
    9. socket=new QTcpSocket (this);
    10. connect(socket,&QTcpSocket::connected,this,&Widget::connected_slot); //
    11. //如果服务器向客户端发来消息,那么该客户端就会自动发射一个readyRead信号
    12. //我们可
    13. connect(socket,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);
    14. //断开
    15. connect(socket,&QTcpSocket::disconnected,this,&Widget::disconnected_slot);
    16. ui->msgEdit->setEnabled(false); //设置消息编辑器不可用
    17. }
    18. static int flag=0;
    19. Widget::~Widget()
    20. {
    21. delete ui;
    22. }
    23. //连接服务器按钮对应的槽函数
    24. void Widget::on_connectBtn_clicked()
    25. {
    26. //判断现在有没有连接上
    27. if(flag==1)
    28. {
    29. //已经连接了不需要再次连接
    30. QMessageBox::information(this,"提示","已连接状态");
    31. return;
    32. }
    33. //获取ui界面上的相关信息
    34. userName=ui->userNameEdit->text(); //获取用户名
    35. QString ip=ui->ipEdit->text(); //主机地址
    36. quint16 port=ui->portEdit->text().toUInt(); //端口号
    37. //函数原型 virtual void connectToHost(const QHostAddress &address, quint16 port, OpenMode mode = ReadWrite);
    38. //功能,将客户端连接到给定的服务器
    39. //参数1,端口号 参数2,端口号
    40. socket->connectToHost(ip,port);
    41. flag=1;
    42. //此时已经像服务器发送连接请求了 ,如果成功连接服务器,那么该客户端会自动发射一个connected的信号
    43. ui->msgEdit->setEnabled(true); //设置消息编辑器可用
    44. ui->ipEdit->setEnabled(false); //设置ip编辑器不可用
    45. ui->portEdit->setEnabled(false); //设置端口号编辑器不可用
    46. ui->userNameEdit->setEnabled(false); //设置用户编辑器不可用
    47. }
    48. //处理connect信号的槽函数的定义
    49. void Widget::connected_slot()
    50. {
    51. QMessageBox::information(this,"成功","您已经成功进入聊天室");
    52. //向服务器发送一条数据
    53. QString msg=userName +":进入聊天室";
    54. socket->write(msg.toLocal8Bit());
    55. }
    56. //自定义处理readyRead信号的槽函数的定义
    57. void Widget::readyRead_slot()
    58. {
    59. //读取套接字中的信息
    60. QByteArray msg=socket->readAll();
    61. //将数据展示到ui界面
    62. ui->msgWidget->addItem(QString::fromLocal8Bit(msg));
    63. }
    64. //发送按钮对应的槽函数
    65. void Widget::on_sendBtn_clicked()
    66. {
    67. //判断现在有没有连接上
    68. if(flag==0)
    69. {
    70. //现在都没连接上发送给谁?
    71. QMessageBox::information(this,"提示","现在没有连接的服务器,发送失败");
    72. return;
    73. }
    74. //获取ui界面输入的内容
    75. QString msg=userName+ ":"+ui->msgEdit->text();
    76. //发送给服务器
    77. socket->write(msg.toLocal8Bit());
    78. }
    79. //断开服务器按钮对应的槽函数
    80. void Widget::on_disconnectBtn_clicked()
    81. {
    82. //判断现在有没有连接上
    83. if(flag==0)
    84. {
    85. //现在都没连接上断开个der
    86. QMessageBox::information(this,"提示","现在没有连接的服务器,无需断开");
    87. return;
    88. }
    89. //告诉大家我走了
    90. QString msg=userName +":离开聊天室";
    91. socket->write(msg.toLocal8Bit());
    92. ui->msgEdit->setEnabled(false); //设置消息编辑器不可用
    93. flag=0;
    94. //断开连接
    95. //无参无返回值
    96. socket->disconnectFromHost();
    97. //当成功与服务器断开连接后
    98. //该客户端会自动发射一个disconnected的信号
    99. //将他绑定到我们自定义的槽函数中,由于该连接只需连接一次即可,放到构造函数中即可
    100. }
    101. //disconnected信号对应槽函数的定义
    102. void Widget::disconnected_slot()
    103. {
    104. QMessageBox::information(this,"提示","退出成功");
    105. }

    现象

  • 相关阅读:
    Halcon知识:三维重构的一个尝试
    Java8新特性实战
    Pandas行列转换
    download failed after attempts=6: dial tcp 108.160.169.178:443: i/o timeout问题解决
    蓝桥杯嵌入式Debug
    Power BI 傻瓜入门 9. 设计和部署数据模型
    java里面封装https请求工具类
    5g路由器赋能园区无人配送车联网应用方案
    栈和队列经典oj面试题
    【linux】centos7 yum安装nginx
  • 原文地址:https://blog.csdn.net/weixin_58469613/article/details/133546892