TcpClient的NetworkStream不接收每个包

时间:2014-11-05 17:47:54

标签: send tcpclient networkstream

我有一部分关于发送和接收使用网络流的代码。我发送两个思想套接字的包但接收方法接收一个包,它包含两个包。我不知道为什么。请帮帮我。

private void ClientReceive()
    {
        try
        {
            DataPackage pakage = null;
            byte[] buffer = null;
            byte[] temp = null;
            int receivebytes = 0;
            while (true)
            {
                Thread.Sleep(500);
                buffer = new byte[1024];
                receivebytes = this.m_stream.Read(buffer, 0, buffer.Length); //bug only receive one package but it contains 2 package, which is sent via "Send" method
                this.m_stream.Flush();
                if (receivebytes == 0)
                {
                    this.IsExit = true;
                    if (this.OnClientExit != null)
                    {
                        this.OnClientExit(this, new ClientExitAvgs(this.ClientInfo, ShutdownType.Shutdown));
                    }
                    this.StopClient();
                    break;
                }
                temp = new byte[receivebytes];
                Array.Copy(buffer, temp, receivebytes);
                pakage = new DataPackage();
                pakage.DataHeader(temp);
                switch (pakage.Cmd)
                { 
                    case Command.Shutdown:  // client shutdown or application close
                        buffer = new byte[4];
                        this.m_stream.Read(buffer, 0, buffer.Length);
                        this.m_stream.Flush();
                        ShutdownType downType = (ShutdownType)BitConverter.ToInt32(buffer, 0);
                        if (OnClientExit != null)
                        {
                            OnClientExit(this, new ClientExitAvgs(this.ClientInfo, downType));
                        }
                        break;
                    case Command.Name:
                        buffer = new byte[pakage.DataLength];
                        this.m_stream.Read(buffer, 0, buffer.Length);
                        this.m_stream.Flush();
                        string regex = Encoding.Unicode.GetString(buffer);
                        this.ClientInfo = ComputerInfo.GetComputerInfo(regex);
                        this.IsReceiveClientInfo = true;
                        break;
                    case Command.USB:
                        buffer = new byte[4];
                        this.m_stream.Read(buffer, 0, 4);
                        this.m_stream.Flush();
                        UsbType type = (UsbType)BitConverter.ToInt32(buffer, 0);
                        UsbAvgs e = new UsbAvgs();
                        e.ClientInfo = this.ClientInfo;
                        e.Usbtype = type;
                        switch (type)
                        {                                
                            case UsbType.NotRegister:       //connected and not register

                                break;
                            case UsbType.Registered:            // register for usb device
                                break;
                            case UsbType.Remove:                // usb device removed
                                break;
                            case UsbType.Connected:         // usb device connected and registered
                                break;
                        }
                        if (this.OnUsbExecute != null)
                        {
                            this.OnUsbExecute(this, e);
                        }
                        break;
                }
            }
        }
        catch
        {

        }
    }

发送方法。我发送了2个包但接收方法收到了一个。

private void ClientSend()
    {
        try
        {
            DataPackage pakage = null;
            byte[] buffer = null;
            while (true)
            {
                Thread.Sleep(500);
                while (this.SendQueue.Count > 0)
                {
                    pakage = new DataPackage();
                    pakage = (DataPackage)this.SendQueue.Dequeue();
                    //send command
                    buffer = package.ToBytesHeader();
                    this.m_stream.Write(buffer, 0, buffer.Length);
                    this.m_stream.Flush(); // send first package
                    //Thread.Sleep(10);
                    switch (pakage.Cmd)
                    {
                        case Command.Name:
                            //send computer name
                            buffer = Encoding.Unicode.GetBytes(ComputerInfo.Regex());
                            this.m_stream.Write(buffer, 0, buffer.Length); //send second package
                            this.m_stream.Flush();
                            break;
                        case Command.USB:
                            while (this.SendQueue.Count == 0) { }
                            UsbType type = (UsbType)this.SendQueue.Dequeue();
                            buffer = null;
                            buffer = BitConverter.GetBytes((int)type);
                            this.m_stream.Write(buffer, 0, buffer.Length);
                            this.m_stream.Flush();
                            break;
                        case Command.Shutdown:
                            while (this.SendQueue.Count == 0) { }
                            buffer = BitConverter.GetBytes((int)(ShutdownType)this.SendQueue.Dequeue());
                            this.m_stream.Write(buffer, 0, buffer.Length);
                            this.m_stream.Flush();
                            break;
                    }
                }
            }
        }
        catch
        {

        }
    }

1 个答案:

答案 0 :(得分:2)

TCP是协议。您不发送“包” - 您发送数据流,并接收数据流。数据在后台分解为数据包的事实是您正在使用的NetworkStream的低级实现细节。

如果您需要打包数据,则必须自行完成。通常,这涉及添加某种标题 - 最简单的形式只是数据的长度 - 后跟数据。然后读取端读取标题,并知道消息中有多少数据。