《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");
    }
}

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;
    }
}

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));
    }
}

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;
        }
    }
}

在这里插入图片描述

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

完整源码下载

在这里插入图片描述

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/126636.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java 设计模式——访问者模式

目录 1.概述2.结构3.案例实现3.1.抽象访问者类3.2.抽象元素类3.3.具体元素类3.4.具体访问者类3.5.对象结构类3.6.测试 4.优缺点5.使用场景6.扩展6.1.分派6.2.动态分配6.3.静态分配6.4.双分派 1.概述 访问者模式 (Visitor Pattern) 是一种行为型设计模式&#xff0c;它用于将数…

jQuery中显示与隐藏

在我们jQuery当中&#xff0c;有多个显示隐藏的方法&#xff0c;本篇介绍一下hide()、show()、toggle() 在我们JS当中&#xff0c;或是CSS当中&#xff0c;我们常用到display:none或block; 在我们jQuery当中&#xff0c;我们该如何实现显示隐藏 在我们jQuery当中&#xff0c;我…

定义无向加权图,并使用Pytorch_geometric实现图卷积

首先定义无向边并定义边的权重 import torch import torch.nn as nn from torch_geometric.nn import GCNConv import torch.nn.functional as F from torch_geometric.data import Dataa torch.LongTensor([0, 0, 1, 1, 2, 2, 3, 4]) b torch.LongTensor([0, 1, 2, 3, 1, 5,…

amazon产品采集数据

导入需要的库&#xff1a;requests&#xff0c;BeautifulSoup&#xff0c;re&#xff0c;chardet requests用于发送HTTP请求&#xff1b;BeautifulSoup用于解析HTML&#xff1b;re用于正则表达式&#xff1b;chardet用于识别网页编码。 定义函数&#xff0c;接受URL参数&#…

c语言初学者用vs还是vscode?

c语言初学者用vs还是vscode? 看是科班还是自学&#xff0c;一般学校会有要求的编译软件&#xff0c;在这两者之间&#xff0c;用VS的居多&#xff0c;一个可能的原因是VS不用自己装环境。 最近很多小伙伴找我&#xff0c;说想要一些 c语言的资料&#xff0c;然后我根据自己从…

Spring的循环依赖问题

文章目录 1.什么是循环依赖2.代码演示3.分析问题4.问题解决5.Spring循环依赖6. 疑问点6.1 为什么需要三级缓存6.2 没有三级缓存能解决吗&#xff1f;6.3 三级缓存分别什么作用 1.什么是循环依赖 上图是循环依赖的三种情况&#xff0c;虽然方式有点不一样&#xff0c;但是循环依…

一个不用充钱也能让你变强的 VSCode 插件!!!

今天给大家推荐一款不用充钱也能让你变强的 vscode 插件 通义灵码&#xff08;TONGYI Lingma&#xff09;&#xff0c;可以称之为 copilot 的替代甜品 &#x1f4aa; 前言 之前一直使用的 GitHub Copilot&#xff0c;虽然功能强大&#xff0c;但是收费相对来说有点贵&#xf…

HTTParty库数据抓取代码示例

使用HTTParty库的网络爬虫程序&#xff0c; ruby require httparty # 设置服务器 proxy_host proxy_port # 使用HTTParty库发送HTTP请求获取网页内容 response HTTParty.get(/, :proxy > { :host > proxy_host, :port > proxy_port }) # 打印获取的网页内容 …

【Python深入学习】- 书籍推荐|数据结构和算法介绍|内建集合数据类型

&#x1f308;个人主页: Aileen_0v0 &#x1f525;系列专栏:PYTHON学习系列专栏 &#x1f4ab;"没有罗马,那就自己创造罗马~" 若把编写代码比作行军打仗&#xff0c;那么要想称霸沙场&#xff0c;不能仅靠手中的利刃&#xff0c;还需深谙兵法。Python是一把利刃&…

解决:AttributeError: ‘WebDriver‘ object has no attribute ‘find_element_by_id‘

解决&#xff1a;AttributeError: ‘WebDriver’ object has no attribute ‘find_element_by_id’ 背景 在使用之前的代码通过selenium定位元素时&#xff0c;报错&#xff1a;selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to loca…

无线测温系统在电厂的必要性,保障电力系统稳定运行

安科瑞电气股份有限公司 上海嘉定 201801 摘要&#xff1a;采集关键电力设备接电的实时温度&#xff0c;克服有线温度监测系统存在的诸如线路多&#xff0c;布线复杂&#xff0c;维护困难等不足&#xff0c;将无线无源传感器与Zigbee无线通信技术相结合&#xff0c;将物联网技…

如何在Visual Studio上创建项目并运行【超级详细】

工欲善其事&#xff0c;必先利其器。想要学好编程&#xff0c;首先要把手中的工具利用好&#xff0c;今天小编教一下大家如何在史上最强大的编译器--Visual Studio上创建项目。&#x1f357; 一.打开编译器&#x1f357; 双击你电脑上的vs&#xff0c;(2012,2019,2022)都行。&…

jQuery中淡入与淡出

在我们jQuery中为我们封装了很多好玩的方法&#xff0c;我为大家介绍一下淡入与淡出&#xff01; 我们需要配合事件来玩淡入淡出 淡出语法&#xff1a;fadeOut([speed,[easing],[fn]) (1)参数都可以省略 (2)speed:三种预定速度之一的字符串(“slow”“normal”or “fast”)或…

实战!工作中常用的设计模式

文章目录 前言一、策略模式1.1、 业务场景1.2 、策略模式定义1.3、 策略模式使用1.3.1、一个接口&#xff0c;两个方法1.3.2、不同策略的差异化实现1.3.3、使用策略模式 二、责任链模式2.1、业务场景2.2、责任链模式定义2.3、责任链模式使用2.3.1、一个接口或者抽象类2.3.2、每…

计网自顶向下(Web服务器+UDPping+邮件客户端)

目录 &#x1f416;前言 &#x1f33c;Web服务器(作业1) &#x1f333;过程 &#x1f333;解释 &#x1f525;代码 &#x1f33c;UDPping程序(作业2) &#x1f333;过程 &#x1f333;解释 Client Server 整体逻辑 &#x1f525;代码 &#x1f33c;邮件客户端(作业…

Postman汉化教程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 Postman汉化教程 前言 前言 Postman是一款支持http协议的接口调试与测试工具&#xff0c;其主要特点就是功能强大&#xff0c;使用简单且易用性好 。无论是开发人员进行接口…

护眼灯买什么样的好?好用又实惠的护眼台灯推荐

护眼台灯的光照一般比较均匀&#xff0c;相比普通台灯&#xff0c;一般具有防蓝光、防频闪等功能&#xff0c;能够提供一个健康舒适的学习、生活灯光环境&#xff0c;建议选购内置智能感光模式的护眼台灯&#xff0c;以确保灯光亮度一直处于均衡状态&#xff0c;让眼睛更轻松。…

【Spring】AOP实现原理

注册AOP代理创建器 在平时开发过程中&#xff0c;如果想开启AOP&#xff0c;一般会使用EnableAspectJAutoProxy注解&#xff0c;这样在启动时&#xff0c;它会向Spring容器注册一个代理创建器用于创建代理对象&#xff0c;AOP使用的是AnnotationAwareAspectJAutoProxyCreator&…

计算机考研精炼1000题:笔试面试必备攻略

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 ⭐️ 好书推荐 计算机考…

Qt5多线程<12>

1.多线程的简单实现 <1> 在头文件threaddlg.h声明用于界面显示所需的控件,其代码如下: #ifndef THREADDLG_H #define THREADDLG_H#include <QDialog> #include <QPushButton> #include "workthread.h" #define MAXSIZE 5class ThreadDlg : publ…