QTcpSocket 发送数据心得

2023-11-12

遇到不会用的函数前,最好还是看看手册QAQ,今天居然吃了这个大亏!!!
先交代一下背景:
在做TCP客户端的发送数据功能,要和服务器程序进行TCP/IP通信,且根据通信协议要发送数组或者结构体,并且数组的每一个位都是有效数据位。因此不能像大多数人一样加blockSize篡改协议内容。。

网上大多数的例子都是

    //用于暂存要发送的数据  
    QByteArray block;  
    //使用数据流写入数据  
    QDataStream out(&block,QIODevice::ReadWrite);  
    //设置数据流的版本,客户端和服务器端使用的版本要相同  
    out.setVersion(QDataStream::Qt_4_6);  

    //设置发送长度初始值为0  
    out << (quint16) 0;  
    //设置发送内容  
    out<<hash;  

    //回到字节流起始位置  
    out.device()->seek(0);  
    //重置字节流长度  
    out << (quint16) (block.size()-sizeof(quint16));  

    //往套接字缓存中写入数据,并发送  
    tcpSocket->write(block);  

数据流在这次并不能排上用场,因为处开字节流长度 被包含在发送内容不说,字节流还会修改char数组里的值!!!(调试了很久都没办法)

但是如果往字节流里添加int类型就不会被修改,因为是字节流,所以可以忽视数据类型传输,这反而也是一个小优点。

首先先要知道,一个char有八个字节,unsign int有32个字节(去掉第一位的正负判断)

such as:
char数组 char[6]=”\0x00\0x00\0x00\0x01\0x01\0x00”
从qDebug block 得出内容变成了 “\0x00\0x00\0x00\0x01\0x00” (已经是去掉了blockSize)
内容明显变动了,0x00是用十六进制来表示一个8位字节。

如果是unsign int = “\0x00\0x00\0x01\0x01”输入到字节流打印block内容还是一样,但是可惜的是一个int 有4个字节,并不能发送自己想要的6个字节的效果,所以就放弃掉这个方法了。

然后我还尝试了调用sys/socket.h sys/tyopes.h试图使用C底层的socket函数来实现TCP通信的时候(感觉放着汽车不用用单车。。) 客户端连接函数connect()已经被QT用掉了,用来实现信号槽。。。。。(无语啊。。)

最后从网上看到了一个大神的博客QTcpSocket 发送和接收数据的几种方法

主要就是放弃字节流直接使用socket->Write()函数,但是一开始我用的时候频频报错,我以为这种方法并不可取,最后把char数组转成字符串也没用。。

1、char型数组或字符串指针转换成QString
char str_data[512];
QString qs_data;
…………
qs_data = QString::fromLocal8Bit(str_data,512); //当然也可以用强制类型转换QString(str_data)
2、QString类型转换为 char指针类型
const char * str_data; //这里一定要加上const,否则会报错!
QString qs_data;
………..
str_data = qs_data.ascii();

然后又从一个试图发结构体类型的问题的帖子里看到了这句话,

 this->client->write((char *)&stu,sizeof(stu));

因为我的char是数组,所以我这样写(new的名字不一样,原理是一样的)

SMUTcpSocket->write(mc_sendBuf,sizeof(mc_sendBuf));
SMUTcpSocket->flush();

成功了!!!!!!!!!!!!

诶,主要自我检讨问题是Write函数的使用上面没有清晰去了解,瞎折腾不少时间。所以下次遇到问题先查查手册,看看Write()函数有几个重载。

感谢感谢前人的努力,让我们少走了弯路。

1、QTcpSocket 继承于QAbstractSocket继承于QIODevice

2、QTcpSocket 提供的几种接收和发送数据方法

write ( const char *, qint64 ) : qint64
write ( const char * ) : qint64
write ( const QByteArray & ) : qint64
writeData ( const char *, qint64 ) : qint64
read ( char * data, qint64 maxSize ): qint64 
read ( qint64 maxSize ):QByteArray
readAll ():QByteArray
readLine ( char * data, qint64 maxSize ):qint64
readLine ( qint64 maxSize = 0 ):QByteArray

3、例子1 write ( const QByteArray & ) : qint64

//用于暂存要发送的数据  
QByteArray block;  
//使用数据流写入数据  
QDataStream out(&block,QIODevice::ReadWrite);  
//设置数据流的版本,客户端和服务器端使用的版本要相同  
out.setVersion(QDataStream::Qt_4_6);  

//设置发送长度初始值为0  
out << (quint16) 0;  
//设置发送内容  
out<<hash;  

//回到字节流起始位置  
out.device()->seek(0);  
//重置字节流长度  
out << (quint16) (block.size()-sizeof(quint16));  

//往套接字缓存中写入数据,并发送  
tcpSocket->write(block);  

3、例子2 write ( const char *, qint64 ) : qint64

QString *a=new QString;  
tcpSocket->write(a,a->length());  

4、例子3 数据流直接使用QIODevice

QDataStream in(tcpSocket);  
in<< quint16(0xFFFF); //此时QIODevice加载了此数据,而且直接发送出去  

quint16 length = 0;  
QDataStream out(tcpSocket);//如果此时tcpSocket直接有数据发送过来  
out >> length;//length获得第一个整型值,并在tcpSocket中清空该数据

PS:最新更新

通过我司某位大神,问题已经找出来了。

之前的问题是为什么把char数组放入字节流里会修改存入字节的内容。

因为指针不是从零开始的(不排除之前有缓存占用了),所以在放入char数组前先

   out.device()->seek(0);

这样子内容就正确了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QTcpSocket 发送数据心得 的相关文章

  • 我的 QSqlQueryModel 不在列表视图中显示数据

    我正在玩 QSqlQueryModel 但我现在完全陷入困境 我一整天都在寻找解决方案 但到目前为止还没有运气 我所做的工作是它从我的 sqlite 数据库中提取数据 但由于某种原因我无法在列表视图中显示它 我的角色名似乎不存在 对于我从数
  • cx_freeze:QODBC 驱动程序未加载

    我的 python 应用程序如下所示 test py from PyQt4 import QtCore from PyQt4 import QtGui from PyQt4 import QtSql import sys import at
  • Windows 消息循环而不是 QApplication::exec() / QApplication::processEvents()

    我是否想念任何一个Qt如果我替换功能QApplication exec 使用标准 Windows 消息循环实现 这应该可以澄清我的意思 运行事件处理的常用 Qt 方式 int main int argc char argv QApplica
  • qt项目如何设置安装路径

    我正在寻找与 qmake configure prefix 等效的内容 基本上 我想覆盖默认的安装 部署目录 这是如何用命令行 qmake 指定的 我还使用 QtCreator 构建了很多 gui 项目 并且我想知道如何在 QtCreato
  • Qt 支持在 QIcon 中为 SVG 着色

    看来 Qt 不支持 SVG 中路径标签上的描边 填充选项
  • QTableView 中的虚拟列?

    我开始学习 Qt4 模型 视图编程 我有初学者问题 我有一个简单的应用程序 其中显示 sqlite 表QTableView class Model QtSql QSqlTableModel def init self parent None
  • 从 QML 实例化 C++ 对象会产生巨大的内存使用开销

    实例化一个QObjectC 堆中的派生类为每个对象提供了大约 160 个字节 通过注册相同的对象qmlRegisterType 用于从 QML 创建并通过以下方式动态创建对象createObject 每个对象给我 2000 多个字节 这是完
  • 仅将非模态 QDialog 窗口放置在我的应用程序顶部,而不是所有应用程序顶部

    我有一个 QDialog 窗口 它应该始终位于我的应用程序顶部 它不是模态的 用户可以随时与对话框和主应用程序进行交互 使用窗口保持在顶部提示在某种程度上实现了这一点 但是 该对话框仍然位于所有其他正在运行的应用程序 例如记事本 chrom
  • Qt程序部署到多平台,如何?

    我是 Qt 编程新手 我想开发一个程序 我想在 Windows Linux ubuntu 和 Mac 上运行 听说Qt支持多平台应用程序开发 但我的问题是 在我部署或编译后 任何 Qt 库都需要在 Ubuntu 中运行这个应用程序吗 如果您
  • 当我尝试构建 Qt 4.7.1 静态库时,“找不到 -ljscore”

    我尝试从最新的源构建静态 Qt 库 但出现以下错误 usr bin ld cannot find ljscore collect2 ld returned 1 exit status 如何解决这个问题呢 这是 Qt 构建系统中自 4 7 0
  • Qt WinRT 应用程序无法访问文件权限被拒绝

    我需要使用 Qt 和 FFMPEG 开发 WinRT 应用程序 我根据指令构建了 WinRT 的 ffmpeghere https github com Microsoft FFmpegInterop我可以将库与我的项目链接起来 现在我需要
  • PyQt:如何设置组合框项目可检查?

    为了将 GUI 小部件数量保持在最低限度 我需要找到一种方法来为用户提供下拉菜单项的选择 这些菜单项可用于过滤掉 listWidget 项中显示的内容 假设 listWidget 列出了 5 个不同类别的项目 Cat A Cat B Cat
  • 禁用 QML Slider 的鼠标滚轮

    我希望能够滚动Flickable使用鼠标滚轮 或触摸板上的两根手指 不改变Sliders它可能包含 示例代码及结果应用 import QtQuick 2 7 import QtQuick Window 2 2 import QtQuick
  • 在 Qt5 中,是否需要 Q_INVOKABLE 来从 QML 调用公共 QObject 函数?

    我刚刚意识到我可以调用暴露于 QML 的对象的几乎任何函数 现在我对 Q INVOKABLE 很好奇 Qt5docs http doc qt io qt 5 qtqml cppintegration exposecppattributes
  • 重定向 python 交互式帮助()

    我正在为使用 Qt 的应用程序开发交互式 python shell 但是我似乎无法获得重定向的交互式帮助 我的 python 代码中有这个 class OutputCatcher def init self self data def wr
  • 如何将图像显示为缩略图

    我有一个QTreeView显示硬盘驱动器和目录 我也有一个QListView显示图像文件如下 但我想将图像显示为缩略图 如下所示 My code mainWidget mainWidget QWidget parent QWidget pa
  • 为 Windows 98 编译 Qt

    我需要支持 Windows 98 Qt 文档声称这是可能的 但没有说明 Qt 4 6 的分布式二进制文件不能在 Win98 上运行 而且我采样的大多数 Qt 应用程序也不能在 Win98 上运行 对于几个确实在 98 上运行的应用程序 我询
  • 更改 Qt OpenGL 窗口示例以使用 OpenGL 3.3

    我正在尝试更改 Qt OpenGL 示例以使用更现代的 opengl 版本 330 似乎合适 所以我做了 在 main cpp 上设置版本和配置文件 设置着色器版本 更改着色器以使用统一 它现在构建没有任何错误 但我只看到一个空白窗口 我错
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • Qt:在多个布局中使用一个小部件

    我有一个 QTabBar 所有选项卡都应该有相同的小部件 layout1 gt addWidget w layout2 gt addWidget w 然而打电话addWidget第二次导致该小部件在第一个布局中消失 有没有办法使用一个小部件

随机推荐

  • 从pandas dataframe中随机删除n个某一列是某个值的元素

    从pandas dataframe中随机删除n个某一列是某个值的元素 import pandas as pd 创建示例 DataFrame data A 1 2 3 4 5 6 B 6 7 8 9 10 11 C X Y Z X Y X d
  • 基本排序算法(直接排序,选择排序,冒泡排序)

    一 直接排序 思路 首先需要两个嵌套的for循环 外层for循环控制轮数 内层for循环控制每轮比较的次数 这里来演示一下遍历的过程 第一轮 首先让i指向数组的首部 让j指向i的后一个元素 两者比较 2比1大 所以交换2跟1的位置 然后j后
  • git proxy

    git config global https proxy http 127 0 0 1 7890 git config global https proxy https 127 0 0 1 7890
  • tar命令的详细解释

    tar命令 root linux tar cxtzjvfpPN 文件与目录 参数 c 建立一个压缩文件的参数指令 create 的意思 x 解开一个压缩文件的参数指令 t 查看 tarfile 里面的文件 特别注意 在参数的下达中 c x
  • CSS 水平居中

    1 若元素内容为文字时 元素设置text align center text align属性指定元素文本的水平对齐方式 center 把文本排列到中间 p 这里是文本内容 p 2 父子元素宽度固定 父元素设置text align cente
  • SQL实用功能手册

    SQL实用功能手册 SQL基础复习 SQL结构化查询语言 是一种访问和处理数据库的计算机语言 对数据库操作 对表操作 对数据进行CRUD操作 操作视图 存储过程 索引 环境基础操作 安装mysql 启动mysql 配置环境变量 检查mysq
  • 搞懂java类加载机制和类加载器

    搞懂java类加载机制和类加载器 类加载概述 一个类从被加载到虚拟机内存中开始 到卸载出内存为止 它的整个生命周期将会经历加载 验证 准备 解析 初始化 使用和卸载七个阶段 其中验证 准备 解析三个部分统称为连接 如下图所示 其中加载 验证
  • Android学习——Adapter适配器

    AdapterView 容器控件 其整体效果由每一个子元素内容决定 子元素的形式由Adapter决定 AdapterView的子视图对象 ListView 以垂直滑动列表形式显示一组数据 GridView 以网格形式显示一组数据 Spinn
  • GPUView的使用

    本文翻译自GPUView的开发者Matt的blog https graphics stanford edu mdfisher GPUView html GPUview可以在 https docs microsoft com en us wi
  • 10个经典的C语言面试基础算法及代码

    本文是码农网原创整理 转载请看清文末的转载要求 谢谢合作 算法是一个程序和软件的灵魂 作为一名优秀的程序员 只有对一些基础的算法有着全面的掌握 才会在设计程序和编写代码的过程中显得得心应手 本文是近百个C语言算法系列的第二篇 包括了经典的F
  • C语言(Head First C)-5_1:使用多个源文件:数据类型和使用头文件声明函数

    该系列文章系个人读书笔记及总结性内容 任何组织和个人不得转载进行商业活动 5 1 使用多个源文件 数据类型和头文件 大程序不等于大源文件 只有一个源文件的话 维护耗时且困难 如何把源文件分解为易于管理的小模块 然后合成一个大程序 正是本章的
  • Append-only及其使用

    Append only 维基百科 Append only 是计算机数据存储的一种属性 将新数据附加到存储中 但现有数据是不可变的 许多数据结构和数据库实现了不可变对象 有效地使它们的数据结构只能追加 实现仅追加数据结构有很多好处 例如确保数
  • android 播放raw音频文件格式,Android 使用mediaplayer播放res/raw文件夹中的音乐的实例...

    Android 使用mediaplayer播放res raw文件夹中的音乐的实例 1 在res文件夹中新建一个文件夹重命名为raw 并且将要播放的音乐放到raw文件夹里面 2 修改layout目录下的xml布局文件 添加3个按钮空间和一个文
  • 计算机硬盘启动设置方法,bios设置硬盘启动,详细教您bios设置硬盘启动操作步骤...

    我们在操作电脑的时候 会遇到要重装系统的情况 每当这种时候我们就会想到通过bios设置来进行系统的重装 所以今天小编就来重点给你们说说关于bios设置硬盘启动的操作步骤 重装系统是我们在使用电脑的时候会经常在遇到问题时采用的解决方法 但说到
  • spring boot 获取yaml配置的对象和数组对象

    一 获取对象 例子 yaml中的配置 permission method POST path auth login spring boot 中 在需要使用到该配置的controller或者service或者专门的配置类中 添加method和
  • 磁盘加新盘扩容

    注 如果有磁盘超过2T 如下调整 使用parted来对GPT磁盘操作 进入交互式模式 没有的话yum安装下 parted dev sdb 将MBR磁盘格式化为GPT parted mklabel gpt 到这就可以进行下面的了 先查看下新磁
  • QT UI不能索引控件

    原因 Qt程序使用的UI h文件并不是最新的UI文件 最新的ui h在bulid文件夹里面了 软件依旧使用旧的ui h文件 简单讲就是先要从 ui生成ui h然后再编译 所以界面未更新实际上是因为ui h这个文件没有更新导致的 解决办法 1
  • 论文阅读-(GLIP)Grounded Language-Image Pre-training (目标检测+定位)

    Paper Grounded Language Image Pre training Code https github com microsoft GLIP 简介 定位任务与图像检测任务非常类似 都是去图中找目标物体的位置 目标检测为给出
  • 好一场逗鹅冤:一瓶老干妈撬动BAT

    近日 号称 南山必胜客 的腾讯法务部将低调做酱料的老干妈送上了热搜 腾讯状告老干妈欠广告费 老干妈则称腾讯遭遇诈骗 双方各执一词 引得不明真相的吃瓜群众热闹围观 01 腾讯被骗 老干妈躺赚 6月29日 广东省深圳市南山区人民法院发布一则民事
  • QTcpSocket 发送数据心得

    遇到不会用的函数前 最好还是看看手册QAQ 今天居然吃了这个大亏 先交代一下背景 在做TCP客户端的发送数据功能 要和服务器程序进行TCP IP通信 且根据通信协议要发送数组或者结构体 并且数组的每一个位都是有效数据位 因此不能像大多数人一