zoukankan      html  css  js  c++  java
  • 游戏开发中AS3和服务端通过socket通讯,如何处理粘包的问题

    TCP协议中,发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾.
    如下几种情况:
    •A.数据完整,只有1个包。(正常)
    •B.数据不全,半个包。(不正常)
    •C.数据完整,多个包。(正常)
    •D.B与C的结合,XX.x个数据包。(不正常)
     
    原因:tcp底层会有一定的延迟合并一下数据包发送。这是流式数据包必定会出现的现象,在网络拥挤时,或者一次投递过多数据的时候非常容易出现。
    所以普遍协议设计的手法是采用 HEAD+BODY的形式。
    HEAD大多数包含一个完整意义的“协议包”的长度,通过该长度来校验当前获得的数据是否有半个包存在。如果有半个包,则不进行处理,等剩下的数据收到后再处理。
     
    使用上述思想处理粘包问题的socket连接的主要代码如下:
     
     1 private function socketDataHandler(event:ProgressEvent):void
     2         {
     3             var hander:IProxy 
     4             var module:uint ;
     5             var method:uint ;
     6             var data:Object ;
     7             
     8             while (bytesAvailable >= 2 ) { //2字节长度,  
     9                 if ( _dataLen == 0){ //之前没有读到数据长度
    10                     _dataLen = readUnsignedShort()   ;
    11                 }
    12                 //其实这里还应该判断一下 _dataLen 是否大于2,不过如果小于2,应该是错误的协议了,判断了也多此一举
    13                 if ( bytesAvailable >= _dataLen ){
    14                     module = readUnsignedByte() ; 
    15                     method = readUnsignedByte() ; 
    16                     //这里要读数据,不能因为没这模块就不读了
    17                     _cashBytes.clear() ;
    18                     readBytes( _cashBytes,0,_dataLen - 2 ) ;
    19                     _dataLen= 0 ; //代表这次的包已经读完了
    20                     //准备派发函数
    21                     hander = _handler[module];
    22                     if (hander != null)
    23                     {
    24                         data = _pack.decode(_cashBytes);
    25                      //    try {
    26                             hander.handleMessage(method,data);
    27                         // }catch (e : Error){
    28                         
    29                         // }
    30                     }else {
    31                         trace(module,"没有找到相关模块");
    32                     }
    33                 } else { //半个包
    34                     break ;
    35                 }
    36             }
    37         }

     注意:上述代码中的break,当检测到了包中数据不完整,出现半包现象时,跳出循环,等待收到剩下的数据后再进行处理。

  • 相关阅读:
    POJ 2136
    POJ 2121
    POJ 2127
    POJ 2126
    POJ 2109
    POJ 2105
    POJ 2101
    POJ 2075
    Uboot — 配置过程
    Uboot — 编译体验
  • 原文地址:https://www.cnblogs.com/hisiqi/p/2852075.html
Copyright © 2011-2022 走看看