2015-01-20 4 views
0

В приведенном ниже примере NamedPipeServer запускается или регистрируется с именем «Передача файлов». NamedPipeServer считывает содержимое исходного файла и создает экземпляр класса «TransferFile», устанавливающий такие атрибуты, как имя исходного файла и содержимое файла (поток). Затем сервер сериализует объект TransferFile и записывает его в поток.Исключение, именованный канал + сериализация

NamedPipeClient подключается к серверу NamedPipeServer, чье имя сервера «Передача файлов». и читает поток. После чтения потока клиент deserializes, чтобы получить объект TransferFile. из объекта FileTransfer клиент создает целевой файл в определенном каталоге с именем из атрибута «FileName» и содержимого (byte []) из «FileContent».

Исключение, когда я использую formatter.Deserialize (pipeClient).

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; 
    } 
} 

именованного канала сервера

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); 
       } 
      } 
     } 

    } 

} 

Названный Client Pipe

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(); 
     } 
    } 
} 

ответ

1

Вы не говорите, что у вас есть исключение, а именно. Но просто глядя на код, наиболее очевидной проблемой является то, что у вас есть поле Stream в вашем TransferFile объекте. Вы не можете сериализовать объект Stream.

Одним из вариантов было бы использовать объект byte[] вместо этого в классе TransferFile. Вы можете инициализировать его из своего файла, используя File.ReadAllBytes().

Обратите внимание, что сериализация всего файла не очень эффективна. Если вы хотите наилучшим образом использовать пропускную способность вашего канала, вы должны пропустить всю схему на основе сериализации и вместо этого использовать BinaryWriter.Write(string) для отправки имени файла, а затем просто записать фактическое содержимое файла в поток.

Например:

Сервер:

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); 
      } 
     } 
    } 

Клиент:

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(); 
    } 
Смежные вопросы