• QT学习day5(QT实现TCP协议)


    作业:利用TCP客户端和服务器实现网络聊天室(简单版QQ)

    1.服务器代码

    widget.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(); //自定义处理newConnection信号的槽函数的声明
    21. void readyRead_slot(); //自定义处理readyRead信号的槽函数的声明
    22. private:
    23. Ui::Widget *ui;
    24. //实例化服务对象
    25. QTcpServer *server;//实例化一个服务器对象
    26. //创一个存放客户端的套接字的容器
    27. QList clientList;
    28. };
    29. #endif // WIDGET_H

    widget.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. //初始化界面(设置不可用)
    11. ui->msgEdit->setEnabled(false);
    12. ui->setBtn->setEnabled(false);
    13. ui->disBtn->setEnabled(false);
    14. //判断是否连接成功,如果连接成功客户端会自动发射connected,将该信号连接到自定义的槽函数中处理相关的逻辑
    15. //因为只需要连接一次,所以我们将连接函数写在构造函数中
    16. connect(socket,&QTcpSocket::connected,this,&Widget::connected_slot);//定义在构造函数是为了只连接一次
    17. //此时说明服务器和客户端此时已经建立好连接,如果服务器发来数据,该客户端会自动发射readRead信号
    18. connect(socket,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);
    19. //判断是否断开成功,如果成功断开连接,客户端自动发射disconnect信号
    20. connect(socket,&QTcpSocket::disconnected,this,&Widget::dis_slot);
    21. }
    22. Widget::~Widget()
    23. {
    24. delete ui;
    25. }
    26. //链接服务器按钮对应的槽函数
    27. void Widget::on_connectStn_clicked()
    28. {
    29. //获取ui界面上的IP和端口号
    30. uesrName=ui->usrnameEdit->text();
    31. QString ip= ui->ipEdit->text();
    32. quint16 port=ui->portEdit->text().toUInt();//转换成整型
    33. //客户端连接链接服务器
    34. socket->connectToHost(ip,port);
    35. }
    36. //连接成功对应的槽函数实现
    37. void Widget::connected_slot()
    38. {
    39. //告诉服务器 我来了
    40. QString msg = uesrName + ":进入聊天室";
    41. //将信息发送给服务器
    42. socket ->write(msg.toLocal8Bit());
    43. //将ui界面上的控价进行相关设置
    44. ui->usrnameEdit->setEnabled(false);
    45. ui->ipEdit->setEnabled(false);
    46. ui->portEdit->setEnabled(false);
    47. ui->connectStn->setEnabled(false);
    48. ui->msgEdit->setEnabled(true);
    49. ui->setBtn->setEnabled(true);
    50. ui->disBtn->setEnabled(true);
    51. }
    52. void Widget::readyRead_slot()//readyread对应的槽函数
    53. {
    54. //说明服务器给客户端发来数据
    55. QByteArray msg = socket->readAll();
    56. //将数据放入到ui界面中
    57. ui->listWidget->addItem(QString::fromLocal8Bit(msg));
    58. }
    59. void Widget::dis_slot()
    60. {
    61. ui->usrnameEdit->setEnabled(true);
    62. ui->ipEdit->setEnabled(true);
    63. ui->portEdit->setEnabled(true);
    64. ui->connectStn->setEnabled(true);
    65. ui->msgEdit->setEnabled(false);
    66. ui->setBtn->setEnabled(false);
    67. ui->disBtn->setEnabled(false);
    68. }
    69. void Widget::on_setBtn_clicked()//发送按钮对应的槽函数处理
    70. {
    71. //获取ui界面上的文本内容
    72. QString msg =uesrName+":"+ ui->msgEdit->text();
    73. //将信息发送给服务器
    74. socket->write(msg.toLocal8Bit());
    75. //将msg的文本清空
    76. ui->msgEdit->clear();
    77. }
    78. void Widget::on_disBtn_clicked()//断开按钮对应的槽函数处理
    79. {
    80. QString msg = uesrName+":"+ "离开了聊天室,尔等也退下吧";
    81. socket->write(msg.toLocal8Bit());
    82. socket->disconnectFromHost();
    83. }

    服务器 ui界面:

     

    2.客户端代码

    second.h

    1. #ifndef SECOND_H
    2. #define SECOND_H
    3. #include
    4. #include
    5. #include//服务器头文件
    6. #include//客户端头文件
    7. #include//消息对话框
    8. #include//调试类
    9. namespace Ui {
    10. class Second;
    11. }
    12. class Second : public QWidget
    13. {
    14. Q_OBJECT
    15. public slots:
    16. void jump_slot();//接收跳转信号函数
    17. public:
    18. explicit Second(QWidget *parent = nullptr);
    19. ~Second();
    20. private slots:
    21. void on_connectBtn_clicked();//链接服务器对应的槽函数声明
    22. void connected_solt();
    23. void readyRead_slot();
    24. void dis_slot();
    25. void on_sendBtn_clicked();
    26. void on_disBtn_clicked();
    27. private:
    28. Ui::Second *ui;
    29. //实例化一个客户端对象
    30. QTcpSocket *socket;
    31. //定义一个用户名的变量
    32. QString userName;
    33. };
    34. #endif // SECOND_H

     

    widget.h 

     

    1. #ifndef WIDGET_H
    2. #define WIDGET_H
    3. #include
    4. #include//动态图
    5. #include//图片
    6. #include//输出
    7. #include//按钮类
    8. #include//信息类
    9. #include//图片
    10. QT_BEGIN_NAMESPACE
    11. namespace Ui { class Widget; }
    12. QT_END_NAMESPACE
    13. class Widget : public QWidget
    14. {
    15. Q_OBJECT
    16. public:
    17. Widget(QWidget *parent = nullptr);
    18. ~Widget();
    19. signals://自定义跳转信号函数
    20. void jump();
    21. private slots:
    22. //void on_pushButton_2_clicked();
    23. void my_slot();//自己定义的槽函数
    24. private:
    25. Ui::Widget *ui;
    26. };
    27. #endif // WIDGET_H

     

    main.cpp

    1. #include "widget.h"
    2. #include"second.h"
    3. #include
    4. int main(int argc, char *argv[])
    5. {
    6. QApplication a(argc, argv);
    7. Widget w;
    8. w.show();
    9. //实例化第二个窗口的对象
    10. Second s;
    11. QObject::connect(&w,&Widget::jump,&s,&Second::jump_slot);
    12. return a.exec();
    13. }

     

    second.cpp

    1. #include "second.h"
    2. #include "ui_second.h"
    3. void Second::jump_slot()//跳转信号槽函数
    4. {
    5. this->show();//将自己的界面进行展示
    6. }
    7. Second::Second(QWidget *parent) :
    8. QWidget(parent),
    9. ui(new Ui::Second)
    10. {
    11. ui->setupUi(this);
    12. //第二个界面的窗口设置
    13. this->setWindowTitle("划水摆烂群");
    14. this->setWindowIcon(QIcon(":/pictrue/eaeb1d87_E780070_63de2b7c.png"));
    15. //ui->listWidget->setStyleSheet("QListWidget { background-color: transparent; }");//设置背景为透明色
    16. //给客户端实例化空间
    17. socket =new QTcpSocket(this);
    18. //初始化界面(未连接服务器时)
    19. ui->msgEdit->setEnabled(false);//消息对话框不可用
    20. ui->sendBtn->setEnabled(false);//发送按钮不可用
    21. ui->disBtn->setEnabled(false);//离线不可用
    22. //判断是否连接成功,如果连接成功客户端会自动发射connected,将该信号连接到自定义的槽函数中处理相关的逻辑
    23. //因为只需要连接一次,所以我们将连接函数写在构造函数中
    24. connect(socket,&QTcpSocket::connected,this,&Second::connected_solt);//定义在构造函数是为了只连接一次
    25. //此时说明服务器和客户端此时已经建立好连接,如果服务器发来数据,该客户端会自动发射readRead信号
    26. connect(socket,&QTcpSocket::readyRead,this,&Second::readyRead_slot);
    27. }
    28. Second::~Second()
    29. {
    30. delete ui;
    31. }
    32. void Second::on_connectBtn_clicked()//链接服务器对应的槽函数
    33. {
    34. //获取ui界面上的IP和端口号
    35. userName=ui->usernameEdit->text();//获取用户名
    36. QString ip=ui->ipEdit->text();//获取ip
    37. quint16 port=ui->portEdit_2->text().toUInt();//获取端口号
    38. //客户端连接服务器
    39. socket->connectToHost(ip,port);
    40. }
    41. void Second::connected_solt()//连接成功对应的槽函数
    42. {
    43. //告诉服务器我上线了
    44. QString msg = userName + ":已上线";
    45. //将消息发送给服务器
    46. socket ->write(msg.toLocal8Bit());
    47. //重新设置ui界面上的控件
    48. ui->usernameEdit->setEnabled(false);
    49. ui->ipEdit->setEnabled(false);
    50. ui->portEdit_2->setEnabled(false);
    51. ui->connectBtn->setEnabled(false);
    52. ui->msgEdit->setEnabled(true);
    53. ui->sendBtn->setEnabled(true);
    54. ui->disBtn->setEnabled(true);
    55. }
    56. void Second::readyRead_slot()
    57. {
    58. //说明服务器给客户端发来数据
    59. QByteArray msg = socket->readAll();
    60. //将数据放入到ui界面中
    61. ui->listWidget->addItem(QString::fromLocal8Bit(msg));
    62. }
    63. void Second::dis_slot()
    64. {
    65. ui->usernameEdit->setEnabled(true);
    66. ui->ipEdit->setEnabled(true);
    67. ui->portEdit_2->setEnabled(true);
    68. ui->connectBtn->setEnabled(true);
    69. ui->msgEdit->setEnabled(false);
    70. ui->sendBtn->setEnabled(false);
    71. ui->disBtn->setEnabled(false);
    72. }
    73. void Second::on_sendBtn_clicked()//发送按钮对应的槽函数
    74. {
    75. //获取ui界面上的文本内容
    76. QString msg =userName+":"+ ui->msgEdit->text();
    77. //将信息发送给服务器
    78. socket->write(msg.toLocal8Bit());
    79. //将msg的文本清空
    80. ui->msgEdit->clear();
    81. }
    82. void Second::on_disBtn_clicked()//离线按钮对应的槽函数
    83. {
    84. QString msg = userName+":"+ "离开了聊天室,尔等也退下吧";
    85. socket->write(msg.toLocal8Bit());
    86. socket->disconnectFromHost();
    87. }

     widget.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. this->setWindowTitle("腾讯QQ");
    10. this->setWindowIcon(QIcon(":/pictrue/20573cf63610bed.jpg"));
    11. //连接登录Btn信号与槽
    12. connect(ui->pushButton_2,&QPushButton::clicked,this,&Widget::my_slot);
    13. ui->zhuceBtn->setStyleSheet("border:1px solid transparent;");
    14. ui->mimaBtn->setStyleSheet("border:1px solid transparent;");//取消边框
    15. /**********************标签设置****************************/
    16. //设置标签背景(动态图)
    17. // QMovie *mv = new QMovie("/*************路径*************/");
    18. // ui->beijinglabel->setMovie(mv);
    19. // mv->start();
    20. //让标签自动使用标签
    21. ui->beijinglabel->setPixmap(QPixmap(":/pictrue/wKjg2lvGWoCAJlJxAADOBePmF24715.jpg"));
    22. ui->beijinglabel->setScaledContents(true);
    23. //设置左上角的标签
    24. // ui->qqlable->setPixmap(QPixmap(":/pictrue/20573cf63610bed.jpg"));
    25. // ui->qqlable->setScaledContents(true);
    26. // ui->qqlable->resize(30,30);//重新设置大小
    27. /**********************登录设置*******************************/
    28. }
    29. Widget::~Widget()
    30. {
    31. delete ui;
    32. }
    33. void Widget::my_slot()//登录按钮对应的槽函数
    34. {
    35. QString userName = ui->zhanghaoEdit->text();//获取账号
    36. QString passWord = ui->mimaEdit->text();//获取密码
    37. //判断登录条件是否满足
    38. if(userName=="admin"&&passWord=="123456")
    39. {
    40. //满足登录条件跳转到聊天室页面
    41. // qDebug() << "deng";
    42. // this->close();
    43. emit jump();
    44. this->hide();//将自己的页面隐藏
    45. }else
    46. {
    47. // qDebug() << "";
    48. QMessageBox::information(this,"提示:","账号或密码错误请重新输入");
    49. //ui->zhanghaoEdit->clear();
    50. }
    51. }

    second的ui界面 

    widget的ui界面 

     

    实现效果: 

    运行出的窗口

     

     密码输入错误弹出的消息对话框和启动服务器成功界面

    输入信息上线成功显示界面 

     消息发送成功界面

    离线显示下线信息

     

  • 相关阅读:
    释放Sqlite数据库占用的多余空间
    项目管理PMP考试技巧
    linux启动停止mysql常见错误
    selenium webdriver 防爬问题 C#
    小米智能电视投屏方法
    JavaEE中的网络原理 Ⅰ-- 应用层
    计算机毕业设计Java家装行业门店订单管理系统(源码+系统+mysql数据库+lw文档)
    探索IP地址定位工具:解读IP数据云的功能与优势
    uni-app积极拥抱社区,创建了开放、兼容的插件系统。
    深度解读:金融企业容器云平台存储如何选型
  • 原文地址:https://blog.csdn.net/m0_69894626/article/details/133967653