前言
做上位機的時候下發(fā)數(shù)據(jù),數(shù)據(jù)是一個結(jié)構(gòu)體,這里就闡述一下怎么通過TCP協(xié)議發(fā)送結(jié)構(gòu)體。
我自己寫的時候主要通過兩種方式,一種是memcpy,另一種是用QDataStream。
先在mainwindow.h頭文件中定義結(jié)構(gòu)體:
struct EDWINWZY
{
char name='A';
int age=1;
}edwinwzy;
1. memcpy方式
1.1 發(fā)送整個結(jié)構(gòu)體
函數(shù)原型為void *memcpy(void *destin, void *source, unsigned n);函數(shù)的功能是從源內(nèi)存地址的起始位置開始拷貝若干個字節(jié)到目標內(nèi)存地址中,即從源source中拷貝n個字節(jié)到目標destin中
//定義bit流
QByteArray transfer;
//使用memcpy之前要分配內(nèi)存空間
transfer.resize(sizeof(struct EDWINWZY));
//data.resize(sizeof(edwinwzy));//寫法和上面一句效果一樣
//內(nèi)存拷貝
memcpy(transfer.data(),&edwinwzy,sizeof(edwinwzy));
//發(fā)送比特流數(shù)據(jù)
tcpSocket->write(transfer);
這種方式似乎就定死了只能發(fā)送結(jié)構(gòu)體大小的數(shù)據(jù),但其實不然,我可以通過QByteArray類的成員函數(shù)append來添加一個乃至多個字節(jié)的數(shù)據(jù)。
下面的append函數(shù)中備選的參數(shù)類型名就說明了很多,我可以添加單個字符,也可以添加n個同一個字符,也可以添加另外一個QByteArray的數(shù)據(jù),即一串比特流數(shù)據(jù),亦可以添加QString類型的數(shù)據(jù)。
1.2 發(fā)送部分數(shù)據(jù)
那這是在發(fā)送完一整個結(jié)構(gòu)體之后再添加數(shù)據(jù),如果我想單獨一個一個發(fā)結(jié)構(gòu)體的變量呢?
那其實直接用append就可以了。
//定義bit流
QByteArray transfer;
transfer.append(edwinwzy.name);
transfer.append(edwinwzy.age);
transfer.append('\n');
//發(fā)送比特流數(shù)據(jù)
tcpSocket->write(transfer);
有個要注意的是,有時候我最后不加換行符,接收端可能會出現(xiàn)無法顯示的情況。這個我只在書中TCPClient項目中出現(xiàn)過,我用串口轉(zhuǎn)網(wǎng)口來接收網(wǎng)口的數(shù)據(jù),在串口端接收到的數(shù)據(jù)都是正常的。
2. QDataStream
這個就類似于C++ 的std::cout了。
不過發(fā)送的數(shù)據(jù)有兩種情況。
2.1 符號<<
第一種情況是直接用<<
符號進行發(fā)送,這種發(fā)送會額外發(fā)送幾個字節(jié)數(shù)據(jù)用來表示我發(fā)送的數(shù)據(jù)所占的字節(jié)數(shù)。
QByteArray tranferdata;
//后面這個QIODevice什么的也可以不選擇添加。
QDataStream out(&tranferdata,QIODevice::WriteOnly|QIODevice::Append);
char A=a,B=b,C=c,D=d;
out<<A<<B<<C<<D;
tcpSocket->write(transfer);
實際上我們收到的字節(jié)數(shù)據(jù)用應該是 04 61 62 63 64,而我們其實只要后面的四個abcd的ascii碼數(shù)據(jù),那這個方法就有點問題了。
2.2 wrieteRawData
下面這個寫原始數(shù)據(jù)的writeRawData
函數(shù)就解決了問題
如果我們要發(fā)送其他類型數(shù)據(jù)(不是char類型),那我們使用這個函數(shù)的時候最好做一個強制類型轉(zhuǎn)換。
QByteArray tranferdata;
//后面這個QIODevice什么的也可以不選擇添加。
QDataStream out(&tranferdata,QIODevice::WriteOnly|QIODevice::Append);
int A=91,B=92;
out.writeRawData((char*)&A,sizeof(A));
out.writeRawData((char*)&B,sizeof(B));
tcpSocket->write(transfer);
這種寫法就解決了多發(fā)送字節(jié)的問題,只不過因為這里AB是以int舉例,所以它們分別占4字節(jié)。
收到的數(shù)據(jù)就應該為 00 00 00 61 00 00 00 62文章來源:http://www.zghlxwxcb.cn/news/detail-601906.html
總結(jié)
這篇博客主要針對TCP發(fā)送結(jié)構(gòu)體數(shù)據(jù)遇到的問題進行了歸納,發(fā)單個以及發(fā)部分情況都可以實現(xiàn)。文章來源地址http://www.zghlxwxcb.cn/news/detail-601906.html
到了這里,關(guān)于QT通過TCP協(xié)議發(fā)送結(jié)構(gòu)體數(shù)據(jù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!