从网络字节流中提出整数
最近在做一個(gè)項(xiàng)目,就是設(shè)計(jì)一套通信協(xié)議,利用nginx來(lái)實(shí)現(xiàn)解析。協(xié)議內(nèi)容是包括整數(shù)和字符串,現(xiàn)在客戶端收到服務(wù)器端發(fā)送的網(wǎng)絡(luò)字節(jié)流時(shí),需要從中提取出整數(shù),再根據(jù)整數(shù)決定發(fā)送數(shù)據(jù)量的大小。如下所示:
p = u->buffer.pos;
num=*(int*)p
p指向接收到的網(wǎng)絡(luò)字節(jié)流,用這么方式解析得到的整形num不是服務(wù)器端發(fā)送的數(shù)字,是一個(gè)很大的數(shù)。不對(duì),于是換了種方式:
memcpy(num,p,sizeof(int));
printf("num is %d\n",*(int*)num);
結(jié)果還是一樣。
但是輸出字節(jié)流p,能看到后面的字符串是能得到的,但是前面的整數(shù)得不到
for(i=0;i<9;i++){
printf("i :%c \n",p[i]);
}
于是改成以16進(jìn)制形式輸出,結(jié)果是可以查看到整數(shù)值:
pos last 0
pos last 0
pos last 0
pos last 5
pos last 77
pos last 67
pos last 70
pos last 31
pos last 66
即第4字節(jié)的那個(gè)5正式服務(wù)器端發(fā)送的數(shù)字,這說(shuō)明網(wǎng)絡(luò)字節(jié)流是對(duì)的。只是不能那樣取出來(lái)。
這個(gè)時(shí)候就必須熟悉網(wǎng)絡(luò)字節(jié)流的概念了,搜了下:
網(wǎng)絡(luò)字節(jié)順序是TCP/IP中規(guī)定好的一種數(shù)據(jù)表示格式,它與具體的CPU類型、操作系統(tǒng)等無(wú)關(guān),從而可以保證數(shù)據(jù)在不同主機(jī)之間傳輸時(shí)能夠被正確解釋。網(wǎng)絡(luò)字節(jié)順序采用big endian排序方式。
主機(jī)字節(jié)序就是我們平常說(shuō)的大端和小端模式:不同的 CPU 有不同的字節(jié)序類型,這些字節(jié)序是指整數(shù)在內(nèi)存中保存的順序 這個(gè)叫做主機(jī)序。
就是網(wǎng)絡(luò)字節(jié)流的序列和主機(jī)的序列可能不一樣,所以需要一些函數(shù)進(jìn)行轉(zhuǎn)換,linux提供了四個(gè)函數(shù):
為了進(jìn)行轉(zhuǎn)換 bsd socket提供了轉(zhuǎn)換的函數(shù) 有下面四個(gè)
htons 把unsigned short類型從主機(jī)序轉(zhuǎn)換到網(wǎng)絡(luò)序
htonl 把unsigned long類型從主機(jī)序轉(zhuǎn)換到網(wǎng)絡(luò)序
ntohs 把unsigned short類型從網(wǎng)絡(luò)序轉(zhuǎn)換到主機(jī)序
ntohl 把unsigned long類型從網(wǎng)絡(luò)序轉(zhuǎn)換到主機(jī)序
?
把代碼改成:
p=u->buffer.pos;
htnum=ntohl(*(int*)p);
printf("htmum=%d,%x\n",htnum,htnum);
搞定得到正確結(jié)果。
這說(shuō)明進(jìn)行網(wǎng)絡(luò)編程時(shí)得注意網(wǎng)絡(luò)字節(jié)流的序列,否則不能提取出對(duì)應(yīng)的數(shù)據(jù)。
轉(zhuǎn)載于:https://www.cnblogs.com/hahawgp/p/3709625.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的从网络字节流中提出整数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 遗传算法图解_遗传算法图解指南
- 下一篇: matlab柱状斜线_Matlab小练习