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 << "\n";
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 << "\n";
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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM