簡體   English   中英

如何在C中使用zlib庫對websocket permessage-deflate進行編碼和解碼?

[英]How to Encode and Decode websocket permessage-deflate using zlib library in C?

我試圖使用per-message-deflate編碼WebSocket有效負載。 我試圖使用一些測試代碼,但我的編碼不正確,請你幫我。

這是我的代碼:

char a[180] = "{\"type\":\"message\",\"channel\":\"C04U0F9CW\",\"text\":\"TestingMessage\",\"id\":757}";
char b[180];
char c[180];
int i;
// deflate
// zlib struct
z_stream defstream;
defstream.zalloc = Z_NULL;
defstream.zfree = Z_NULL;
defstream.opaque = Z_NULL;
defstream.avail_in = (uInt)strlen(a)+1; // size of input, string + terminator
defstream.next_in = (Bytef *)a; // input char array
defstream.avail_out = (uInt)sizeof(b); // size of output
defstream.next_out = (Bytef *)b; // output char array

//deflateInit(&defstream, Z_SYNC_FLUSH);
deflateInit2(&defstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY);
deflate(&defstream, Z_SYNC_FLUSH);
deflateEnd(&defstream);
for(i=0;i<=(char*)defstream.next_out - b;i++)
{
        printf("%X",(Bytef)b[i]);
}
printf("\n%s\n",(Bytef *)b);
// This is one way of getting the size of the output
printf("Deflated size is: %lu\n", (char*)defstream.next_out - b);

我的輸出是

kml@kml-VirtualBox:~/zlib-1.2.11/test$ gcc test.c -lz && ./a.out 
789CAA562AA92C4855B252CA4D2D2E4E4C4F55D2514ACE48CCCB4BCD18A391B98841AB8593A873454B522B4A804221A9C5259979E9BE70D599294A56E6A6E6B5C0000FFFF2E
x��V*�,HU�R�M-.NLOU�QJ�H��K��9���Y:�EKR+J�B!��%�y��pՙ)JV����

Deflated size is: 72
Inflate:
73
{"type":"message","channel":"C04U0F9CW","text":"TestingMessage","id":757}

所以我期待有效載荷讓我這樣

AA562AA92C4855B252CA4D2D2E4E4C4F55D2514ACE48CCCB4BCD018A391B98841AB8593A8703454B522B4A804221A9C5259979E9BE70D599294A56E6A6E6B50000

這是該特定消息的fiddler WebSocket流量捕獲

請幫助我獲得正確的per-message-deflate編碼。

Here is some more upgrade information
GET https://127.0.0.1/websoc.html HTTP/1.1
Host: mpmulti-yklu.slack-msgs.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: FriWg0AWhiLhLXXnfJK8kA==
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket

響應

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: S2Q+O/tRM0/mIG//Er2hDdqD0eY=
Sec-Websocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover
X-Via: haproxy-ext90

代碼是正確的,但defstream.avail_in期望精確的長度,而不是額外的空字符。 如果您將提供確切的輸入長度,它將正常工作。 試試這樣吧

int l = (uInt)strlen(a);
defstream.avail_in = l; // size of input, string + terminator

請嘗試了解z_stream如何分配值檢查代碼,然后您將更好地了解這一點。

我想很多人都在嘗試解碼,而且他們沒有為每個消息放棄獲得適當的價值。

檢查你的輸出

789CAA562AA92C4855B252CA4D2D2E4E4C4F55D2514ACE48CCCB4BCD18A391B98841AB8593A873454B522B4A804221A9C5259979E9BE70D599294A56E6A6E6B5C0000FFFF2E

這里789C是標題和0000FFFF或根據你的代碼(00FFFF)是deflate消息的預告片。 這里0代表00,因為你的輸出是打印一個'0'而不是'00'。 因為額外的一個尺碼,你得到額外的5C。 當您嘗試下面的代碼時,Thye'2E'也將被移除

int d = memcmp(msgend, &b[defstream.total_out - 4], 4) ? 0 : 4;
for(i=0;i<defstream.total_out - d;i++)
{
        printf("%2X",(Bytef)b[i]);
}

所以你的預期答案是

AA562AA92C4855B252CA4D2D2E4E4C4F55D2514ACE48CCCB4BCD018A391B98841AB8593A8703454B522B4A804221A9C5259979E9BE70D599294A56E6A6E6B50000

根據您的輸出,2個字節為0,因此根據您的代碼,它將為“00”並且您的輸出跟隨打印每個半字節(半字節)。

請嘗試這對我有用,我現在能夠正確解碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM