http协议之chunk数据结构

转自: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 ;
}

猜你喜欢

转载自cshbbrain.iteye.com/blog/1832830
今日推荐