做了一个多线程文件发送和接收的小程序。socket采用异步的方式发送和接收。代码如下: private void OnEndReceiveData(IAsyncResult ar2)
        {
            int receiveLength = 0;
            SocketStateObject so = null;
            so = (SocketStateObject)ar2.AsyncState;
            if ( so.WorkSocket != null && so.WorkSocket.Connected )
            {
                try
                {
                    receiveLength = so.WorkSocket.EndReceive( ar2 );
                }
                catch
                {
                    //socket已经断开
                    TSession.SetSessionStatus( so.IPPortValue , EnumSessionState.Closed );
                }
                if ( receiveLength > 0 )
                {
                    try
                    {                        TDatagram.ResolveBuffer( TSession.GetSessionFromIPPort( so.IPPortValue ) , so.buffer , receiveLength );
                        ReceiveDone.Set( );                        //继续取数据
                        if ( so.WorkSocket != null && so.WorkSocket.Connected )
                        {
                            so.WorkSocket.BeginReceive( so.buffer , 0 ,
                                            so.BUFFER_SIZE , SocketFlags.None , EndReceiveData , so );                            ReceiveDone.WaitOne( );
                        }
                    }
                    catch
                    {
                        ReceiveDone.Set( );
                    }
                }
                else
                {
                    ReceiveDone.Set( );
                    //socket已经断开
                    TSession.SetSessionStatus( so.IPPortValue , EnumSessionState.Closed );
                }
            }
            else
            {
                ReceiveDone.Set( );
                TSession.SetSessionStatus( so.IPPortValue , EnumSessionState.Closed );            }        }在每一个包的头和尾都加了标志,用于区分一个完整包。但发现在分析包数据时会出现receiveLength的长度,和接收到的so.buffer中的数据不一致。receiveLength的长度会小于so.buffer中实际接收到的数据长度。so.buffer中不为空的有效数据的长度大于receiveLength的长度。难道是缓冲区溢出?
请高手帮忙分析一下,感激不尽!!!

解决方案 »

  1.   

    http://topic.csdn.net/u/20080623/08/4bbd2475-45f1-42e3-a613-16b094759ade.html
      

  2.   

    http://www.itstrike.cn/Home.mvc/Search/?key=socket
      

  3.   

    不知道你的ResolveBuffer()的处理逻辑如何。
    要注意TCP是流传输,每次接收的数据量是不定的,不会正好是一个包,可能是小半个,
    也可能是一个多。
    另外你的so.buffer在每次接收中是重用的,也就是说上次接收的数据若比这次长,
    那么你在so.buffer中的后边实际上可以看到上次的部分数据。
      

  4.   

    这个跟发送缓冲区也有关系。
    当第一次读包不是一个完整的包时,
    要继续读,直到把这个包读对才行
    不要担心会丢数据,TCP是不会的。要做的就是等下个包的到来
      

  5.   

    TCP 是流传输,不是包传输,就是说SOCKET 接收到的数据不是固定的!!你必须自己定义包长度,然后根据接受到的长度,自己构建完整的包。
      

  6.   

    http://hi.baidu.com/wangzhe1945/blog/item/c32513f46f7927e87709d707.html这个比较详细,可以看下为什么会这样。
      

  7.   

    rtdb说的对,so.buffer被重用了,在多线程中其值会被其它线程改了,所以造成数据取的不对。
      

  8.   

    异步容易发生粘包的问题,服务端需要一个监听socket和多个工作的workerSocket