封包时发现的关于QIODevice类write函数的坑
關于QIODevice類write函數的坑
- 問題概述
- 問題部分代碼
- 問題解決
- 結論
問題概述
這兩天在做TCP通信的封包解包協議操作時,不經意間被write函數坑了好久。通過內存復制進行數據封包,在寫入socket的時候總是寫入一個字節,不能全部寫入數據,原先以為是內存復制出了問題,沒想到最后是出在了write函數的使用上。
問題部分代碼
//包頭結構與包尾結構的初始化HEAD head;TAIL tail;head.dataHead = PACK_HEAD;head.dataType = PACK_TYPE;tail.daraTail = PACK_TAIL;strcpy(head.fileName,fileNames[sendTime].toLatin1().data());strcpy(head.filePath,paths[sendTime].toLatin1().data());head.fileSize = fileSizes[sendTime];char *buffer = new char[4*1024]; //內存緩存locFile.setFileName(paths[sendTime]);locFile.open(QIODevice::ReadOnly);do{char buf[2*1024];qint64 readLen = locFile.read(buf,sizeof(buf));head.dataLen = readLen; //包內數據長度DATA *param = (DATA *)buf;memcpy(buffer,&head,sizeof(HEAD));memcpy(buffer+sizeof(HEAD),param,readLen);memcpy(buffer+sizeof(HEAD)+readLen,&tail,sizeof(TAIL));int packLen = readLen+sizeof(HEAD)+sizeof(TAIL); //包總長度/qint64 sendLen = tcpSocket->write(buffer); //問題就出在這里tcpSocket->waitForBytesWritten();//qDebug()<<sendLen;sendSize += readLen;} while (sendSize < fileSizes[sendTime]);問題解決
在這里就不得不說一下,QIODevice類的write()函數了,它有以下三種方法:
1、qint64 QIODevice::write(const char * data, qint64 maxSize)
2、qint64 QIODevice::write(const char * data)
3、qint64 QIODevice::write(const QByteArray & byteArray)
第三種就不說了,傳入的就是一個QByteArray類型的集合就可,由上述可見,第一種比第二種多個一個參數,就是寫入字節數的參數。
等等,你是不是以為第二種和第一種沒什么區別呢,第二種沒有參數表示寫入多少字節數就是表示默認寫入所有的內容嗎!!不是的,請看幫助文檔里的:
strlen(char*)函數求的是字符串的實際長度,它求得方法是從開始到遇到第一個’\0’,buffer是字符型數組,在這里qstrlen(buffer)=1,因此總是寫入是1個字節。
結論
所以為了不出錯,還是選用第一個write()函數,則上述錯誤代碼改為:
qint64 sendLen = tcpSocket->write(buffer,buf.size()); 就可以完全寫入了。
總結
以上是生活随笔為你收集整理的封包时发现的关于QIODevice类write函数的坑的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 十天冲刺-04
- 下一篇: Matlab-Simulink文件类型总