jjzjj

c++ - 读取 QTcpSocket

coder 2024-02-12 原文

我有一个与 UNIX C++ 套接字的套接字连接,连接后,我有一个逐字节读取的循环,直到我获得完整的消息。我知道我将要接收的消息的前两个字节及其长度(15 个字节)。所以函数看起来像:

bool mastControl::findPacket(int sockfd, st_messageMastToPc * messageReceived, bool * connected) {

    int n = 0;
    bool messageFound = false;
    char * buffer = (char *) messageReceived;

    unsigned int pos = 0;

    while ( ((n = read(sockfd, &(buffer[pos]), 1)) > 0) and not messageFound) {

         if (n == 1) {
            pos++;

            if ( (pos == 1) && (buffer[0] == 0x02)) { // First byte to receive
                std::cout << "INFO - Rcv1" << std::endl;
            } else if ( (pos == 2) && (buffer[1] == 0x33) ) { // Second byte
                std::cout << "INFO - Rcv2" << std::endl;
            } else if (pos >= uiMessageMastToPcSize) { // Full msg received
                messageFound = true;
                std::cout << "INFO - Complete message received" << std::endl;
            } else if (pos <= 2) { // Wrong values for the first 2 bytes
                std::cout << "WARN - Reseting (byte " << pos << " -> " << int(pos) << ")" << std::endl;
                pos = 0;
            }
        }
    }

    if (n < 0){
        //EROR
        *connected = false;
    }

    return messageFound;
}

现在我正在使用 QTcpSockets 实现相同的功能。建立连接,然后我调用:

if(socket->waitForReadyRead(Global::tiempoMaximoDeEsperaParaRecibirDatosMastil)){
                /* Read socket to find a valid packet */
                if (findPacket(socket, &messageReceived)) {
                    qDebug()<<"New packet found!";
//...
}
}

所以我等到有一些信息准备好供您读取,然后调用 findPacket,现在几乎相同,逐字节读取:

bool mastControl::findPacket(QTcpSocket *socket, st_messageMastToPc * messageReceived) {
    int n = 0;
    bool messageFound = false;
    char * buffer = (char *) messageReceived;
    unsigned int pos = 0;

    while ( ((n = socket->read(&(buffer[pos]), 1)) >= 0) and not messageFound) {
        if (n == 1) {
            qDebug()<<"Recibido: "<<buffer[pos]<<", en pos: "<<pos;
            pos++;
            if ( (pos == 1) && (buffer[0] == 0x022)) {
                qDebug()<<"0x02 in first position";
//                std::cout << "INFO - Rcv1" << std::endl;
            } else if ( (pos == 2) && (buffer[1] == 0x33) ) {
                qDebug()<<"0x33 in second";
                std::cout << "INFO - Rcv2" << std::endl;
            } else if (pos >= uiMessageMastToPcSize) {
                messageFound = true;
                std::cout << "INFO - Complete message received" << std::endl;
            } else if (pos <= 2) {
                std::cout << "WARN - Reseting (byte " << pos << " -> " << int(pos) << ")" << std::endl;
                pos = 0;
            }
        }
    }

    if (n < 0){
      qDebug()<< "Disconnected. Reason: " << socket->errorString();
    }

    return messageFound;
}

看起来很像,但行不通。在等待 waitForReadyRead 后,我进入 findPacket 的循环并且我能够读取接收到的前 4 个字节。之后,不再接收到数据。它仍然在 findPacket 的循环中一次又一次地检查,但是读取函数总是返回 0 字节读取。没有收到新信息。这是不可能的,因为服务器每隔几毫秒发送一次相同的数据包,所以即使我丢失了一些数据,最终我也应该读到一些东西。

那么,我做错了什么?我应该以不同的方式等待吗?我应该再次等待第一次读取函数返回 0 字节读取吗?这个读取函数和 C++ 库函数有什么区别?

最佳答案

最后,问题在于尝试一直读取,而不是在读取函数返回第一个零之后等待新数据。这样做就像一个魅力!

关于c++ - 读取 QTcpSocket,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10444154/

有关c++ - 读取 QTcpSocket的更多相关文章

  1. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  4. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  5. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  6. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

  7. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  8. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  9. ruby - 是否可以在不实际发送或读取数据的情况下查明 ruby​​ 套接字是否处于 ESTABLISHED 或 CLOSE_WAIT 状态? - 2

    s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成

  10. ruby - 如何从 ARGF 读取 csv - 2

    在Ruby1.9中,我如何从ARGF中读取CSV?我尝试了以下方法,但没有打印任何内容:require'csv'CSV(ARGF).readdo|row|prowendhttp://www.ruby-doc.org/core-1.9.3/ARGF.htmlhttp://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV.html 最佳答案 如果你想偷懒你可以试试:CSV.new(ARGF.file).eachdo|row|...end来源:http://www.ruby-doc.org/std

随机推荐