TCP粘包的拆包处理

因为TCP是流式处理的,所以包没有边界,必须设计一个包头,里面表示包的长度(一般用字节表示),根据这个来逐个拆包。如果对于发送/接收频率不高的话,一般也就不做拆包处理了,因为不大可能有粘包现象。

以下是粘包和拆包的分析:

http://blog.csdn.net/zhangxinrun/article/details/6721495

用Qt的TCPSocket读出的数据来拆:

http://www.aiuxian.com/article/p-1732805.html

我是根据以上链接例子Qt的逻辑来实现的,用Boost的ASIO来读取,是同步的:

 1 m_imp->m_thread = boost::make_shared<boost::thread>(
 2             [=]()
 3             {
 4                 while (!boost::this_thread::interruption_requested())
 5                 {
 6                     boost::this_thread::interruption_point();
 7 
 8                     try
 9                     {
10                         boost::system::error_code ec;
11                         std::vector<uint8_t> tmpreadBuffer(1024 * 500);
12                         
13                         size_t bytes_transferred = m_imp->m_sockPtr->read_some(boost::asio::buffer(tmpreadBuffer), ec);
14 
15                         std::cout << "Byte Transfered:" << bytes_transferred << "
";
16 
17                         if (!ec)
18                         {
19                             
20                             if (bytes_transferred == 0)  continue;
21                             
22                             if (bytes_transferred < MSG_HEAD_SIZE)
23                             {
24                                 m_imp->m_readBuffer.insert(m_imp->m_readBuffer.end(), tmpreadBuffer.begin(), tmpreadBuffer.begin() + bytes_transferred / sizeof(uint8_t));
25                                 continue;
26                             }
27                             else
28                             {
29                                 m_imp->m_readBuffer.insert(m_imp->m_readBuffer.end(), tmpreadBuffer.begin(), tmpreadBuffer.begin() + bytes_transferred / sizeof(uint8_t));
30                                 
31                                 size_t totalSize = m_imp->m_readBuffer.size()*sizeof(uint8_t);
32 
33                                 while (totalSize)
34                                 {
35                                     size_t msgSize = m_imp->getMsgLen();
36                                     std::cout << "Msg Size is:" << msgSize << "
";
37                                     
38                                     std::vector<uint8_t>::const_iterator first = m_imp->m_readBuffer.begin();
39                                     std::vector<uint8_t>::const_iterator last = m_imp->m_readBuffer.begin() + msgSize / sizeof(uint8_t);
40                                     std::vector<uint8_t> tmpMsg(first, last);
41 
42                                     m_imp->m_msgQueue.push_back(tmpMsg);
43 
44                                     m_imp->m_readBuffer.erase(first, last);
45 
46                                     totalSize = m_imp->m_readBuffer.size()*sizeof(uint8_t);
47 
48                                     
49                                 }
50 
51                             }
52                             
53                             
54 
55                            
56 
57 
58                         }
59                         else
60                         {
61                             std::cerr << "recv error : RAC module!" << ec.message() << std::endl;
62                             m_imp->m_sockPtr->close();
63                             break;
64                         }
65                     }
66                     catch (std::exception& e)
67                     {
68                         std::cerr << e.what() << std::endl;
69                         m_imp->m_sockPtr->close();
70                         break;
71                     }
72                 }
73             }
74             
75             
76             
77             );
View Code

以下一个附带干货,以前一直不太理解Qt的TCPSocket,下面是底层原理:

http://blog.csdn.net/ying_593254979/article/details/17006507

原文地址:https://www.cnblogs.com/foohack/p/4739704.html