• 《QT从基础到进阶·十六》QT实现客户端和服务端的简单交互


    QT版本:5.15.2
    VS版本:2019

    客户端程序主要包含三块:连接服务器,发送消息,关闭客户端
    服务端程序主要包含三块:打开消息监听,接收消息并反馈,关闭服务端

    1、先打开服务端监听功能

    void TCPServer::listen()
    {
        initWsaData();
        //创建套接字
        sock = socket(AF_INET, SOCK_STREAM, 0);
        //创建地址簇对象
        sockaddr_in sin;
        sin.sin_family = AF_INET;
        sin.sin_port = htons(9888);
        sin.sin_addr.s_addr = htonl(INADDR_ANY);
        //绑定套接字
        int bindStatus = ::bind(sock, (struct sockaddr*)&sin, sizeof(sin));
        if (bindStatus == -1) {
            qDebug() << "socket bind failed!" << endl;
            ui.textBrowser->setText("socket bind failed!");
            return;
        }
        else {
            qDebug() << "socket bind success!" << endl;
            ui.textBrowser->setText("socket bind success!");
        }
        //将套接字设为监听模式,等待客户端连接
        int listenStatus = ::listen(sock, 128);
        if (listenStatus == -1) {
            qDebug() << "listen failed" << endl;
            ui.textBrowser->setText("listen failed");
            return;
        }
        else {
            qDebug() << "set listen success, server is listening..." << endl;
            ui.textBrowser->setText("set listen success, server is listening...");
        }
        //收到请求主后,接收连接请求,返回一个对应此次连接的新套接字
        //接受连接请求
        sockaddr_in sinAccept;
        int len = sizeof(sin);
        newSock = accept(sock, (struct sockaddr*)&sinAccept, &len);
        if (newSock == SOCKET_ERROR) {
            qDebug() << "connect failed" << endl;
            ui.textBrowser->setText("connect failed");
            return;
        }
        else {
            qDebug() << "connect success, ready to recv data" << endl;
            ui.textBrowser->setText("connect success, ready to recv data");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    2、点击客户端connect连接服务端

    void TCPClient::Connect(const std::string ip, const int port)
    {
        bool res = initWsaData(); //初始化套接字库
        if (!res) return;
    
        //常用协议族:AF_UNIX(本机通信)AF_INET(TCP/IP – IPv4)AF_INET6(TCP/IP – IPv6)
        //套接字类型:SOCK_STREAM(TCP流)SOCK_DGRAM(UDP数据报)SOCK_RAW(原始套接字)
        //protocol”一般设置为“0”
        sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock == SOCKET_ERROR) {
            qDebug() << "Failed to create socket" << endl;
            ui.textBrowser->setText("Failed to create socket");
            return;
        }
        else {
            qDebug() << "Socket created successfully" << endl;
            ui.textBrowser->setText("Socket created successfully");
        }
    
        //设置地址
        sockaddr_in sin;
        sin.sin_family = AF_INET;
        sin.sin_port = htons(port);
        sin.sin_addr.s_addr = inet_addr(ip.c_str());
    
        //连接服务器
        int connStatus = ::connect(sock, (struct sockaddr*)&sin, sizeof(sin));
        if (connStatus == -1) {
            qDebug() << "Failed to connect to the server" << endl;
            ui.textBrowser->setText("Failed to connect to the server");
            return;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    3、在客户端输入消息点击send发送到服务端

    void TCPClient::DataTransmission()
    {
        string msg = ui.lineEdit->text().toStdString();
        /*char sendBuf[MAX_MSG_SIZE];
        memset(sendBuf, 0, MAX_MSG_SIZE)*/;
        
        int sendStatus = send(sock, msg.c_str(), MAX_MSG_SIZE, 0);
        if (sendStatus == 0) {
            qDebug() << "Failed to send information" << endl;
            ui.textBrowser->setText("Failed to send information");
    
            //关闭套接字及套接字库
            closesocket(sock);
            WSACleanup();
            return;
        }
    
        char recvBuf[MAX_MSG_SIZE];
        memset(recvBuf, 0, MAX_MSG_SIZE);
        int recvStatus = recv(sock, recvBuf, MAX_MSG_SIZE, 0);
        if (recvStatus == -1) {
            qDebug() << "Failed to receive message" << endl;
            ui.textBrowser->setText("Failed to receive message");
    
            //关闭套接字及套接字库
           /* closesocket(sock);
            WSACleanup();*/
            return;
        }
        else {
            qDebug() << "Server information:" << recvBuf << endl;
            string msg = "---------Server information:" + string(recvBuf);
            ui.textBrowser->setText(QString::fromStdString(msg));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    4、在服务端点击send接收客户端消息并通知客户端已收到消息

    void TCPServer::DataTransmission()
    {
        //用新建立的套接字和客户端进行通信
        char recvBuf[MAX_MSG_SIZE];
        char sendBuf[MAX_MSG_SIZE];
        memset(recvBuf, 0, MAX_MSG_SIZE);
        memset(sendBuf, 0, MAX_MSG_SIZE);
        if (true) {
            int recvStatus = recv(newSock, recvBuf, MAX_MSG_SIZE, 0);
            if (recvStatus == -1) {
                qDebug() << "recv data failed" << endl;
                ui.textBrowser->setText("recv data failed");
                closesocket(sock);
                closesocket(newSock);
                WSACleanup();
                return;
            }
            else {
                qDebug() << "recv client new msg:" << recvBuf << endl;
                string msg = "--------------recv client new msg:" + string(recvBuf);
                ui.textBrowser->setText(QString::fromStdString(msg));
            }
            /*qDebug() << "请输入回复消息:";
            cin >> sendBuf;*/
            string sendMsg = "has recv msg-------";
            int sendStatus = send(newSock, sendMsg.c_str(), sizeof(sendBuf), 0);
            if (sendStatus == -1) {
                qDebug() << "msg send failed" << endl;
                ui.textBrowser->setText("msg send failed");
                closesocket(sock);
                closesocket(newSock);
                WSACleanup();
                return;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    在这里插入图片描述

    =====================

    完整源码下载

    在这里插入图片描述

    📢博客主页: 主页
    📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
    📢本文由 梦回阑珊 原创,首发于 CSDN,转载注明出处🙉
    📢代码改变世界,你来改变代码!✨

  • 相关阅读:
    【开题报告】基于SpringBoot的网上摄影工作室的设计与实现
    使用 nuxt3 开发简约优雅的个人 blog
    解压游戏资源,导出游戏模型
    linux进程间通讯--信号量
    python之元组介绍
    防御---003
    【量化交易】 量化因子 情绪类因子计算
    nodeJs 图片下载功能实现
    【个人学习笔记】概率论与数理统计知识梳理【六】
    YOLOv5-训练自己的VOC格式数据集(VOC、自建数据集)
  • 原文地址:https://blog.csdn.net/cs1395293598/article/details/134326045