tcp-資料包
阿新 • • 發佈:2019-01-11
我們往往使用tcp協議傳輸資料,都會自定義一個包裹,本次分享下對包的理解,其基本結構如下:
在傳送端,我們只需要將完整的包裹一次傳送出去即可,eg
// 位元組 QByteArray bytes; PackageInfo info; info.exUse_int = 1000; info.exUse_char = '1'; // bodyLen 非定長 info.dataSize = buffer.size(); QDataStream stream(&bytes,QIODevice::WriteOnly); // head stream << info.exUse_int << info.exUse_char << info.dataSize; // body bytes.append(buffer.data()); socket->write(bytes);
接受時,由於傳送端告知傳送的資料總位元組數,以及body位元組數,所以我們可以在接受端判斷接收,直到完整接收。
if(bytesAvailable() <= 0) { return; } // 總快取,每次不滿就存入,清空問題待處理 static QByteArray bytes; // head,定長 const static int headLen = sizeof(unsigned int) + sizeof(unsigned char) + sizeof(qint64); QByteArray t_bytes = readAll(); bytes.append(t_bytes); if(bytes.size() < headLen) { // 繼續快取 return; } // head已經完整get,獲取真實資料長度 PackageInfo info; QDataStream stream(&bytes, QIODevice::ReadOnly); stream >> info.exUse_int >> info.exUse_char >> info.dataSize; // 讀滿 if(bytes.size() < info.dataSize + headLen) { // 繼續快取 return; } // bodyData QByteArray dataBytes = bytes.right(bytes.size() - headLen); // to do
我們一次傳送很大的包裹,接收時是多次的,因為,像tcp這種水龍頭流水,你用杯子接水,至於你接了多少水不可控。因此我們使用靜態變數儲存,或者成員變數,每次填充到快取中並比較要接收的大小,直到完整get即可。這裡就是告訴客戶端,你需要接收多大,一個完整的包裹。
關於Tcp協議,粘包問題,等仍需要處理。至於涉及的高併發等深入問題仍需要學習。