转自:http://hi.baidu.com/iunkown1987/item/005e7c1a1edf27f7746a8426
chunk编码其实是一种动态数据传输协议,针对大数据可以动态传输,网页可以动态显示。
chunk编码格式如下:
[chunk size][\r\n][chunk data][\r\n][chunk size][\r\n][chunk data][\r\n][chunk size = 0][\r\n][\r\n]
chunk size是以十六进制的ASCII码表示,比如3361,计算成长度应该是:58,表示从回车之后有连续的58字节的数据。
chunk数据以0长度的chunk块结束。
使用boost::asio写了一个用于接收chunk数据块的函数如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
bool
recv_chunk_body( boost::asio::ip::tcp::socket& request,
char
**body_buffer, unsigned
int
*body_length )
{
unsigned
int
chunk_size = 0;
unsigned
int
total_size = 0;
char
chunk_end[2] = {0};
try
{
while
( recv_chunk_head( request, &chunk_size ) )
{
if
( chunk_size != 0 )
{
total_size += chunk_size;
*body_buffer = (
char
*)
realloc
( *body_buffer, total_size );
boost::asio::read( request, boost::asio::buffer( *body_buffer + total_size - chunk_size, chunk_size ) );
//////////////////////////////////////////////////////////////////////////
// 数据接收完成,再接收剩下的两个字节"\r\n"
boost::asio::read( request, boost::asio::buffer( chunk_end, 2 ) );
}
else
{
//////////////////////////////////////////////////////////////////////////
// 数据接收完成,再接收剩下的两个字节"\r\n"
boost::asio::read( request, boost::asio::buffer( chunk_end, 2 ) );
break
;
}
}
}
catch
(...)
{
return
false
;
}
*body_length = total_size;
return
true
;
}
/*
* 这里一个字节一个字节的接收
*/
bool
recv_chunk_head( boost::asio::ip::tcp::socket& request, unsigned
int
*chunk_size )
{
char
c = 0;
int
index = 0;
char
chunk_header[128] = {0};
bool
chunk_header_end =
false
;
boost::
system
::error_code error_code;
try
{
while
( !chunk_header_end && index < 128 )
{
boost::asio::read( request, boost::asio::buffer( &c, 1 ), error_code );
chunk_header[ index++ ] = c;
//////////////////////////////////////////////////////////////////////////
// 判断chunk header是否接收完成
if
( index >= 2 )
{
if
( chunk_header[index - 2] ==
'\r'
&& chunk_header[index - 1] ==
'\n'
)
{
chunk_header_end =
true
;
}
}
}
}
catch
(...)
{
return
false
;
}
//////////////////////////////////////////////////////////////////////////
// 如果chunk header接收完成,判断是否还有数据需要接收
*chunk_size =
strtol
( chunk_header, NULL, 16 );
return
true
;
}
|