zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    通过点击切换文本框内容的脚本示例
    使用脚本改变树控件的行为
    javascript动态创建radio button元素支持IE/Firefox
    轻量级的向导控件MultiView
    客户端脚本简单实现Repeater的无刷新分页
    在非web site项目中引用Membership
    逐步认识C#四种判断相等的方法
    C#获取csv文件内容对逗号和引号分隔的处理
    JavaScript之 值类型 和 引用类型 Better
    JS call apply bind 方法的区别 Better
  • 原文地址:https://www.cnblogs.com/foohack/p/4739704.html
Copyright © 2011-2022 走看看