举例说明C#异步Socket接收模式下的Socket缓冲区使用

在使用Socket的 异步接收时,需要定义一个对象:
/// <summary>
/// 传输对象
/// </summary>
public class TranslateObj
{
  /// <summary>
  /// 缓冲区
  /// </summary>
  public byte[] bytes;
  /// <summary>
  /// 缓冲区大小
  /// </summary>
  public const int BUFFER_SIZE = 512;
  /// <summary>
  /// 存放重复接收数据的列表
  /// </summary>
  public ArrayList tmpAl;
  /// <summary>
  /// 接收/发送数据的Socket
  /// </summary>
  public Socket csock;
  public TranslateObj()
  {
   this.csock = null;
   this.bytes = new byte[BUFFER_SIZE];
   this.csock = null;
  }
  ~TranslateObj()
  {
   this.tmpAl = null;
   this.csock = null;
  }
}
使用时,调用下述方法:
private void ReceiveStart(Socket thisSocket)
{
      TranslateObj obj = new TranslateObj();
      obj.csock = thisSocket;
      obj.bytes = new byte[TranslateObj.BUFFER_SIZE];
      obj.tmpAl = new ArrayList(2048);
      obj.csock.BeginReceive(obj.bytes,0,TranslateObj.BUFFER_SIZE,0,
       new AsyncCallback(ReceiveCallBack),obj);
}
/// <summary>
  /// 异步接收回调函数
  /// </summary>
  /// <param name="ar"></param>
  private void ReceiveCallBack(IAsyncResult ar)
{
    TranslateObj obj = (TranslateObj)ar.AsyncState;
    int revCount = obj.csock.EndReceive(ar);
   if(revCount >0)//如果接收的内容长度大于0
{
   ;//一般情况下,在此调用接收数据事件完成对接收数据的处理,问题就在此,如果此处接收的数据包长度大于BUFFER_SIZE,那么就会出现数据包不齐,下一个数据包就会粘连!解决此问题的方法:
//使用ArrayList:
byte[] tmpbytes = new byte[revCount];
Array.Copy(obj.bytes,0,tmpbytes,revCount);
obj.tmpAl.AddRange(tmpbytes);
if(obj.csock.Available >0)
{
obj.bytes = new byte[obj.csock.Available];
obj.csock.BeginReceive(obj.bytes,0,obj.csock.Available,0,
       new AsyncCallback(ReceiveCallBack),obj);//再次投递接收事件,把缓冲区内容全部接收
}
else
{
byte[] endreceive = new byte[obj.tmpAl.Count];
tmpAl.CopyTo(endreceive);
//在此触发数据接收事件,接收内容就是endreceive中的内容
}
}

posted @ 2013-01-11 10:09  蓬莱  阅读(2119)  评论(1编辑  收藏  举报