经过断点跟踪发现在这行中:
ntStream.Write(sendBytes, 0, (int) sendStream.Length);
sendStream.Length 的值为 182但是到了这行,却发现:
int bytesRead = stream.Read(bytes, 0, (int) client.ReceiveBufferSize);
byresRead 的值为 176为什么前后两个值有偏差呢?奇怪了,希望大家能够看看,谢谢。

解决方案 »

  1.   

    ntStream.Write(sendBytes, 0, (int) sendStream.Length); 
    后面有调用Flush吗
      

  2.   


    没有用哦,以下是 NetworkStream.Flush() 在MSDN中的描述:[b]备注
    Flush 方法实现 Stream.Flush 方法,但是因为 NetworkStream 不进行缓冲处理,所以此方法对网络流无效。调用 Flush 方法不会引发异常。[/
    b]
      

  3.   

    在服务器端发送数据的代码下面加一行暂停线程多少秒的函数(SELLP函数),一般暂停200毫秒左右!
      

  4.   

    汗。。粘包
    方法(如果数据较大可以分包发送),给发送的数据包加上头信息,一般我喜欢设的顺序是包长,包个数,第几个包等等
    具体的方法你可以去网上查找一下tcpip通讯的分包组包
      

  5.   

    需要发送的数据为message中的内容,下面是将message序列化,然后写入NetworkStream private NetworkStream ntStream; 
    private TcpClient myTCPclient;
    // 
    // 
    //发送数据到 
    public static void Send(string myStr) 

        ArrayList message = new ArrayList(); 
        message.Add(myStr);  
        // 
        // 序列化要传送的数据到临时流 
        // 
        MemoryStream mStream = new MemoryStream(); 
        BinaryFormatter formatter = new BinaryFormatter(); 
        formatter.AssemblyFormat = FormatterAssemblyStyle.Simple; 
        formatter.TypeFormat = FormatterTypeStyle.TypesWhenNeeded; 
        formatter.Serialize(mStream, message); 
        mStream.Flush(); 
        // 
        // 写入流头 
        // 
        MemoryStream sendStream = new MemoryStream(); 
        Byte[] buffer; 
        // 
        // 写验证标识 (1 字节) 
        // 
        buffer = BitConverter.GetBytes(isValidate); 
        sendStream.Write(buffer, 0, buffer.Length); 
        // 
        // 写临时流长度 (4 字节) 
        // 
        buffer = BitConverter.GetBytes((int) mStream.Length); 
        sendStream.Write(buffer, 0, buffer.Length); 
        // 
        // 写发送标识 (4 字节) 
        // 
        buffer = BitConverter.GetBytes(StreamID ++); 
        sendStream.Write(buffer, 0, buffer.Length); 
        // 
        // 写入临时流到发送流 
        // 
        Byte[] mbuffer = mStream.GetBuffer(); 
        sendStream.Write(mbuffer, 0, (int) mStream.Length); 
        sendStream.Flush();     Byte[] sendBytes = sendStream.GetBuffer(); 
        ntStream.Write(sendBytes, 0, (int) sendStream.Length); 
    } 以下代码为读出NetworkStream,在收到NetworkStream后,将其反序列化: 
    // 
    //将接收到的信息进行再分配处理 
    // 
    public static ArrayList ReceiveScheduler(TcpClient client, NetworkStream stream) 

        byte[] bytes = new byte[client.ReceiveBufferSize]; 
        ArrayList message = null;     int bytesRead = stream.Read(bytes, 0, (int) client.ReceiveBufferSize); // 提示这行出错。     if (bytesRead > 0)// 图过信息队列中,信息内容不为空,则读出 
        { 
            try 
            { 
                int sendLength = BitConverter.ToInt32(bytes, 1) + 9;             if (sendLength == bytesRead) 
                { 
                    MemoryStream mStream = new MemoryStream(bytes, 9, sendLength - 9); 
                    BinaryFormatter formatter = new BinaryFormatter(); 
                    formatter.AssemblyFormat = FormatterAssemblyStyle.Simple; 
                    formatter.TypeFormat = FormatterTypeStyle.TypesWhenNeeded; 
                    message = (ArrayList) formatter.Deserialize(mStream); 
                    message.Add(BitConverter.ToUInt32(bytes, 5)); 
                } 
            } 
            catch 
            { 
    // 
    // 忽略 
    // 
              } 
        }     return message; 
    } /////////////////////////////
    用的时候
    private void button1_Click(object sender, System.EventArgs e)
    {
        string myStr1 = "aaaaaaa";
                Send(myStr1);                    // 测试用,第一次断点时,放在此处;第二次断点时放再 Send(myStr2)后面;发现两次的 bytesRead 值都一样
        byte[] bytes = new byte[myTCPclient.ReceiveBufferSize];
        int bytesRead = ntGameServerManagerStream.Read(bytes,0,myTCPclient.ReceiveBufferSize);

                        ReceiveScheduler(myTCPclient, ntStream);                    string myStr2 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
                        Send(myStr2);
    }
    首先将 myStr1 写入ntStream ,然后用函数 ReceiveScheduler(myTCPclient, ntStream) 将 ntStream 读出;然后再向 ntStream 写入 myStr2 ;运行的时候断点发现,两次 bytesRead 的值都是一样的,是不是我第二次写入ntStream的时候没有成功呢?这是什么原因呢?麻烦大家帮忙看看,非常感谢。
      

  6.   

    你把ArrayList的内容弄成实体对象试试!!
      

  7.   

    string myStr1 = "aaaaaaa";
                Send(myStr1);    byte[] bytes = new byte[10240];
        int bytesRead = ntGameServerManagerStream.Read(bytes,0,myTCPclient.ReceiveBufferSize);
                        ReceiveScheduler(myTCPclient, ntStream);                    string myStr2 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
                        Send(myStr2); 
    int bytesRead2 = ntGameServerManagerStream.Read(bytes,0,myTCPclient.ReceiveBufferSize);
    这样测下,看接收的大小还一样吗?按理说不一样。
      

  8.   

    请不要用 mStream.GetBuffer(), 把它替换为mStream.ToArray()。
    因为mStream.GetBuffer()并不是获取的整个内存流的数据,而是内部缓冲区的数据。
      

  9.   

    以下摘自MSDN:GetBuffer()返回从其创建此流的无符号字节数组。[C#]
    public virtual byte[] GetBuffer();返回值
    创建此流所用的字节数组;或者如果在当前实例的构造期间没有向 MemoryStream 构造函数提供字节数组,则为基础数组。
    ToArray()
    将整个流内容写入字节数组,而与 Position 属性无关。[C#]
    public virtual byte[] ToArray();返回值
    新字节数组。