2017-05-03 103 views
4

全部 我正在嘗試使用per-message-deflate對WebSocket有效載荷進行編碼。我試圖使用一些測試代碼,但我的編碼是不正確的,你可以幫我。如何在C中使用zlib庫對websocket permessage-deflate進行編碼和解碼?

這裏是我的代碼:

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); 

我的輸出是

[email protected]:~/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 

This is the fiddler WebSocket traffic capture for that particular message

請幫助我出去得到正確的每個消息放氣編碼。

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 

回答

0

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

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

請嘗試瞭解z_stream是如何分配值檢查代碼,那麼你會更好地瞭解這一點。

我認爲很多人都在嘗試解碼,他們沒有得到適當的價值每消息泄氣。

檢查輸出

789CAA562AA92C4855B252CA4D2D2E4E4C4F55D2514ACE48CCCB4BCD18A391B98841AB8593A873454B522B4A804221A9C5259979E9BE70D599294A56E6A6E6B5C0000FFFF2E

這裏789C是報頭和0000FFFF或根據代碼(00FFFF)是放氣消息的拖車。這裏0代表00,因爲你的輸出是打印一個'0'而不是'00'。由於額外的一個尺寸,你得到5C額外。泰豐「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',你的輸出將按照每個半字節打印(半字節)。

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

相關問題