简体   繁体   English

异常,命名管道+序列化

[英]Exception, named pipe + serialization

In the below example, NamedPipeServer is started or registered with name “File Transfer”. 在以下示例中,名称为“ File Transfer”的NamedPipeServer已启动或注册。 The NamedPipeServer reads the content of a source file and creates an instance for “TransferFile” class setting the attributes such as source file name and file content (stream). NamedPipeServer读取源文件的内容,并为“ TransferFile”类创建实例,以设置诸如源文件名和文件内容(流)之类的属性。 Server then serializes the "TransferFile" object and writes to the stream. 然后,服务器序列化“ TransferFile”对象并写入流。

NamedPipeClient connects to the NamedPipeServer based whose server name is “File Transfer”. NamedPipeClient连接到基于NamedPipeServer的服务器,其服务器名称为“文件传输”。 and reads the stream. 并读取流。 After reading the stream, Client deserializes to get the “TransferFile” object. 读取流后,客户端反序列化以获取“ TransferFile”对象。 from the “FileTransfer” object, client creates the target file in specific directory with name from “FileName” attribute and content(byte[]) from “FileContent”. 客户端通过“ FileTransfer”对象在特定目录中创建目标文件,该目标文件的名称来自“ FileName”属性,内容(byte [])来自“ FileContent”。

Exception, when i use formatter.Deserialize(pipeClient). 例外,当我使用formatter.Deserialize(pipeClient)时。

TransferFile.cs TransferFile.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;

namespace FileTransfer
{
    //file transfer class (serializable)
    [Serializable]
    public class TransferFile
    {
        public string FileName;
        public Stream FileContent;
    }
}

Named Pipe Server 命名管道服务器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Pipes;
using System.Threading;
using System.Runtime.Serialization;
using FileTransfer;

namespace ServerNamedPipe
{
    class Program
    {
        static void Main()
        {
            //creating object for file transfer
            using (NamedPipeServerStream pipeServer =
                new NamedPipeServerStream("File Transfer", PipeDirection.Out))
            {
                Console.WriteLine("File Transfer Named Pipe Stream is ready...");
                Console.Write("Waiting for client connection...");//waiting for any client connections
                pipeServer.WaitForConnection();
                Console.WriteLine("Client connected.");
                try
                {
                    string strFile = @"c:\Test\1\Srinivas.txt";

                    //creating FileTransfer Object ans setting the file name
                    TransferFile objTransferFile = new TransferFile() { FileName = new FileInfo(strFile).Name };
                    objTransferFile.FileContent = new MemoryStream();

                    //opening the source file to read bytes
                    using (FileStream fs = File.Open(strFile, FileMode.Open, FileAccess.Read))
                    {
                        byte[] byteBuffer = new byte[1024];
                        int numBytes = fs.Read(byteBuffer, 0, 1024);

                        //writing the bytes to file transfer content stream
                        objTransferFile.FileContent.Write(byteBuffer, 0, 1024);

                        //below code is to write the bytes directly to the pipe stream
                        //pipeServer.Write(byteBuffer, 0, 1024);

                        //Reading each Kbyte and writing to the file content
                        while (numBytes > 0)
                        {
                            numBytes = fs.Read(byteBuffer, 0, numBytes);
                            objTransferFile.FileContent.Write(byteBuffer, 0, 1024);

                            //below code is to write the bytes to pipe stream directly
                            //pipeServer.Write(byteBuffer, 0, numBytes);
                        }

                        //setting the file content (stream) position to begining
                        objTransferFile.FileContent.Seek(0, SeekOrigin.Begin);

                        //serializing the file transfer object to a stream
                        IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                        try
                        {
                            //serialzing and writing to pipe stream
                            formatter.Serialize(pipeServer, objTransferFile);
                        }
                        catch (Exception exp)
                        {
                            throw exp;
                        }
                    }
                }
                // Catch the IOException that is raised if the pipe is
                // broken or disconnected.
                catch (IOException e)
                {
                    Console.WriteLine("ERROR: {0}", e.Message);
                }
            }
        }

    }

}

Named Pipe Client 命名管道客户端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Pipes;
using System.Runtime.Serialization;

namespace ClientNamedPipe
{
    class Program
    {
        static void Main(string[] args)
        {
            //connecting to the known pipe stream server which runs in localhost
            using (NamedPipeClientStream pipeClient =
                new NamedPipeClientStream(".", "File Transfer", PipeDirection.In))
            {


                // Connect to the pipe or wait until the pipe is available.
                Console.Write("Attempting to connect to File Transfer pipe...");
                //time out can also be specified
                pipeClient.Connect();

                Console.WriteLine("Connected to File Transfer pipe.");

                IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                //deserializing the pipe stream recieved from server
                FileTransfer.TransferFile objTransferFile = (FileTransfer.TransferFile)formatter.Deserialize(pipeClient);

                //creating the target file with name same as specified in source which comes using
                //file transfer object
                byte[] byteBuffer = new byte[1024];

                using (FileStream fs = new FileStream(@"c:\Test\2\" + objTransferFile.FileName, FileMode.Create, FileAccess.Write))
                {
                    //writing each Kbyte to the target file
                    int numBytes = objTransferFile.FileContent.Read(byteBuffer, 0, 1024);
                    fs.Write(byteBuffer, 0, 1024);
                    while (numBytes > 0)
                    {
                        numBytes = objTransferFile.FileContent.Read(byteBuffer, 0, numBytes);
                        fs.Write(byteBuffer, 0, numBytes);
                    }
                }
                Console.WriteLine("File, Received from server: {0}", objTransferFile.FileName);
            }
            Console.Write("Press Enter to continue...");
            Console.ReadLine();
        }
    }
}

You don't say what exception you got, specifically. 您没有说具体是什么异常。 But just looking at the code, the most obvious problem is that you have a Stream field in your TransferFile object. 但是仅查看代码,最明显的问题是TransferFile对象中具有Stream字段。 You can't serialize a Stream object. 您无法序列化Stream对象。

One option would be to use a byte[] object instead in the TransferFile class. 一种选择是在TransferFile类中使用byte[]对象。 You can initialize it from your file using File.ReadAllBytes() . 您可以使用File.ReadAllBytes()从文件中对其进行初始化。

Note that serializing the whole file is not very efficient. 请注意,序列化整个文件不是很有效。 If you want to make the best use of your pipe bandwidth, you should skip the whole serialization-based scheme, and instead use BinaryWriter.Write(string) to send the file name, and then just write the actual contents of the file to the stream. 如果要充分利用管道带宽,则应跳过整个基于序列化的方案,而应使用BinaryWriter.Write(string)发送文件名,然后将文件的实际内容写入到流。

For example: 例如:

Server: 服务器:

    static void Main()
    {
        //creating object for file transfer
        using (NamedPipeServerStream pipeServer =
            new NamedPipeServerStream("File Transfer", PipeDirection.Out))
        {
            Console.WriteLine("File Transfer Named Pipe Stream is ready...");
            Console.Write("Waiting for client connection...");//waiting for any client connections
            pipeServer.WaitForConnection();
            Console.WriteLine("Client connected.");
            try
            {
                string strFile = @"c:\Test\1\Srinivas.txt";

                using (BinaryWriter writer = new BinaryWriter(pipeServer, Encoding.UTF8, true))
                {
                    writer.Write(strFile);
                }

                //opening the source file to read bytes
                using (FileStream fs = File.Open(strFile, FileMode.Open, FileAccess.Read))
                {
                    fs.CopyTo(pipeServer);
                }
            }
            // Catch the IOException that is raised if the pipe is
            // broken or disconnected.
            catch (IOException e)
            {
                Console.WriteLine("ERROR: {0}", e.Message);
            }
        }
    }

Client: 客户:

    static void Main(string[] args)
    {
        //connecting to the known pipe stream server which runs in localhost
        using (NamedPipeClientStream pipeClient =
            new NamedPipeClientStream(".", "File Transfer", PipeDirection.In))
        {
            // Connect to the pipe or wait until the pipe is available.
            Console.Write("Attempting to connect to File Transfer pipe...");
            //time out can also be specified
            pipeClient.Connect();

            Console.WriteLine("Connected to File Transfer pipe.");

            using (BinaryReader reader = new BinaryReader(pipeClient, Encoding.UTF8, true))
            {
                string fileName = reader.ReadString();
            }

            //creating the target file with name same as specified in source which comes using
            //file transfer object
            using (FileStream fs = new FileStream(@"c:\Test\2\" + fileName, FileMode.Create, FileAccess.Write))
            {
                pipeClient.CopyTo(fs);
            }
            Console.WriteLine("File, Received from server: {0}", fileName);
        }
        Console.Write("Press Enter to continue...");
        Console.ReadLine();
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM