【问题标题】:NetworkStream of TcpClient does not receive each packageTcpClient 的 NetworkStream 不接收每个包
【发布时间】:2014-11-06 01:51:53
【问题描述】:

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

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
        {

        }
    }

【问题讨论】:

    标签: send tcpclient networkstream


    【解决方案1】:

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

    如果您需要打包数据,则必须自己进行。通常这涉及添加某种标题——最简单的形式就是数据的长度——然后是数据。然后读取方读取header,就知道消息中有多少数据了。

    【讨论】:

    • 嗨,谢谢你的回答。我用错了这个词。“包”是指数据。我想问:从发送到接收是同步的。在我的问题中,首先:我发送 4 个字节,然后我连续发送 4 个字节,但我收到 8 个字节。我想接收 4 个字节并连续接收 4 个字节。对不起,我的英语水平不好。
    • @HungLe:所以一次只读取 4 个字节(但不要假设一次调用 Read 肯定会读取所有 4 个字节...)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    • 1970-01-01
    • 2017-05-10
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    相关资源
    最近更新 更多