Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 反序列化通过TCP发送的数据_C#_.net_Serialization_Tcp - Fatal编程技术网

C# 反序列化通过TCP发送的数据

C# 反序列化通过TCP发送的数据,c#,.net,serialization,tcp,C#,.net,Serialization,Tcp,我无法通过TCPClient发送对象。首先,我将它们序列化为字节数组,然后发送它们。TCPListener接收到一些数据,但反序列化程序正在引发异常“意外的流结束” 以下是接收器代码: public void start() { TcpListener listener = new TcpListener(IPAddress.Any, 8090); listener.Start(); while (true) {

我无法通过TCPClient发送对象。首先,我将它们序列化为字节数组,然后发送它们。TCPListener接收到一些数据,但反序列化程序正在引发异常“意外的流结束”

以下是接收器代码:

    public void start()
    {
        TcpListener listener = new TcpListener(IPAddress.Any, 8090);
        listener.Start();

        while (true)
        {
            TcpClient client = listener.AcceptTcpClient();
            processClient(client);
        }
    }

    public void processClient(TcpClient client)
    {
        NetworkStream net = client.GetStream();


        ReadData(net);

        byte[] response  = Encoding.UTF8.GetBytes("Hello from the server.");
        net.Write(response, 0, response.Length);
        net.Close();
        client.Close();
    }

void ReadData(NetworkStream netstream)
{
    byte[] buffer = new byte[2048];
    System.IO.MemoryStream memStream = new System.IO.MemoryStream();

    netstream.ReadTimeout = 5000;

    int bytes = -1;

    while ((bytes = netstream.ReadByte()) != -1)
    {
        memStream.WriteByte((byte)bytes);
    }

    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bform = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();


    Packet packet = (Packet)bform.Deserialize(memStream);

    OnMessageArrived(this, new MessageEventArgs(packet.From.ToString(), packet.Data.ToString()));

    memStream.Close();
    netstream.Close();

}
这是发件人代码:

    public void sendData(string to, Packet data)
    {
        TcpClient client = new TcpClient();

        MemoryStream mstream = new MemoryStream();

        client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8090));
        if (client.Connected)
        {
            NetworkStream stream = client.GetStream();

            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bform = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

            bform.Serialize(mstream, data);

            byte[] buffer = new byte[2048];
            mstream.Read(buffer, 0, buffer.Length);

            stream.Write(buffer, 0, buffer.Length);
            stream.Flush();
            stream.Close();
            client.Close();
        }
    }
发送者主要方法:

    static void Main(string[] args)
    {
        SimplestTCPIP.Client client = new SimplestTCPIP.Client();

        Packet packet = new Packet("client", "server", IPAddress.Parse("127.0.0.1"));

        client.sendData("server", packet);

        Console.WriteLine("IP: " + GetIP().ToString());
        Console.Read();
    }
    static void Main(string[] args)
    {
        SimplestTCPIP.Server server = new SimplestTCPIP.Server();

        server.OnMessageArrived += new SimplestTCPIP.Server.MessageArrived(server_OnMessageArrived);

        Thread thread = new Thread(server.start);
        thread.Start();

    }

    static void server_OnMessageArrived(object sender, SimplestTCPIP.Server.MessageEventArgs m)
    {
        Console.WriteLine(m.From + " : " + m.Text);
    }
接收器主要方法:

    static void Main(string[] args)
    {
        SimplestTCPIP.Client client = new SimplestTCPIP.Client();

        Packet packet = new Packet("client", "server", IPAddress.Parse("127.0.0.1"));

        client.sendData("server", packet);

        Console.WriteLine("IP: " + GetIP().ToString());
        Console.Read();
    }
    static void Main(string[] args)
    {
        SimplestTCPIP.Server server = new SimplestTCPIP.Server();

        server.OnMessageArrived += new SimplestTCPIP.Server.MessageArrived(server_OnMessageArrived);

        Thread thread = new Thread(server.start);
        thread.Start();

    }

    static void server_OnMessageArrived(object sender, SimplestTCPIP.Server.MessageEventArgs m)
    {
        Console.WriteLine(m.From + " : " + m.Text);
    }

在sendData方法中,将对象序列化为内存流,然后在将其写入网络流之前将其读回2048字节的缓冲区。如果序列化对象大于2048字节,则会出现问题。我会尝试直接序列化到网络流,或者至少使用与ReadData方法相同的代码,在ReadData方法中逐字节写入

编辑:

数据的大小可能不是问题所在。您仍然应该避免硬编码的缓冲区大小,并坚持您在注释中提到的代码更改。根据你的评论,问题在别处。 在发送方和接收方中,您都向内存流写入数据,然后从中读取数据。除非在写入和读取之间将流中的当前位置设置回零,否则无法执行此操作

因此,在客户端的sendData方法中添加以下行

mstream.Seek(0, SeekOrigin.Begin);
memStream.Seek(0, SeekOrigin.Begin);
紧接着

bform.Serialize(mstream, data);
在服务器的ReadData方法中添加以下行

mstream.Seek(0, SeekOrigin.Begin);
memStream.Seek(0, SeekOrigin.Begin);
就在之前

Packet packet = (Packet)bform.Deserialize(memStream);
这样,在您尝试读取内存流之前,内存流就被设置为开始


我认为您可以跳过所有内存流,只读取和写入网络流,但可能还有其他原因。

我尝试了以下代码:while((bytes=mstream.ReadByte())!=-1){stream.WriteByte((byte)bytes);stream.Flush()}但它抛出了另一个例外:(类似于“尝试重建空流”。你有解决过这个问题吗?