Socket sock = (Socket)ar.AsyncState;
         
            int nBytesRec = sock.EndReceive(ar);            
            if (nBytesRec > 0)
            {
                try
                {
                    //把当前接收到的缓存放到 tempByt
                     Array.Copy(this._buffer, 0, tempByt,this._position, nBytesRec);
                     this._position += nBytesRec;
                  
                    //报文长度数据
                    byte[] lenByt = new byte[4];
                    Array.Copy(tempByt, 0, lenByt, 0, 4);                    string bufferstr = Encoding.ASCII.GetString(tempByt);//测试
                    string allstr = Encoding.ASCII.GetString(this._buffer);//测试                    //报文长度
                    this._length = int.Parse(Encoding.ASCII.GetString(lenByt));
                    if (this._position < this._length)
                    {
                        if (sock.Poll(-1, SelectMode.SelectRead)) // 已经有数据等待接收
                        {
                            //继续接收数据
                            ReceiveMessage();
                        }                      
                    }
                    else
                    {
                        //接收到的数据
                        byte[] recByt = new byte[this._length-8];
                        Buffer.BlockCopy(tempByt, 0, recByt, 8, this._length - 8);
                        packetList.Enqueue(recByt);//放进队列                                                //移除当前已处理的数据包
                        Array.Clear(tempByt, 0, this._length);
                        this._position = this._position - this._length;                        if (sock.Poll(-1, SelectMode.SelectRead)) // 已经有数据等待接收
                        {
                            //继续接收数据
                            ReceiveMessage();
                        }    
                    }
                }
                catch (Exception ex)
                {
                    this.Close();
                    throw new Exception(ex.ToString());
                }
            }
            else
            {
                sock.Shutdown(SocketShutdown.Both);
                sock.Close();
            }比如我发送了320字节长度的Byte[]数据,第一次总是接收到期15个字节,经调试第二次接收的时候第16,17个字节丢失.请问如何才能完全接收呢?

解决方案 »

  1.   

    TCP是流式协议,所以对端通过多个包发送的数据的确可能在接收端只用一次recv就全部收到,尤其是异步方式的情况。也可能只收到一个包的一部分。 所谓流式协议就是说没有所谓的包的概念,通信双方只能将数据作为流来处理。数据中的语义必须自己定义边界。 另外,就我所知异步方式就不存在什么阻塞问题了。.net的框架自动帮你解决了这个事情。需要注意的是回调函数实际上是处于另一个线程的上下文。因此你需要注意异步回调函数执行过程的线程同步问题,以及STAThreading下窗口控件的调用问题。
      

  2.   

    我定义的通讯协议:报文长度|报文ID|报文内容,前面"报文长度"和"报文ID"分别占4个字节,每次先读报文长度,然后截按长度取包,问题是我总是接收不够报文长度的字节
      

  3.   

    if (this._position < this._length) 
                        { 
                            if (sock.Poll(-1, SelectMode.SelectRead)) // 已经有数据等待接收 
                            { 
                                //继续接收数据 
                                ReceiveMessage(); 
                            }                      
                        } 
    ReceiveMessage();
    这个里面做了什么,可以在接收一个包长度后,同步读取该包的剩下部分。
      

  4.   

    我猜你对数组的操作有问题,丢掉了些内容。
    请试验不做任何处理,一直观察接收的_buffer。
    如二楼所说的回调是新线程,看看这边处理的时候那边是不是又回调了,然后你还。
      

  5.   

    初步估计echoserver返回时有问题,结贴算了