0

另一方面,我有兩個應用程序監聽網絡流:Server.cs;發送文件Client.cs。但我想從任何文件夾的流發送更多的文件。例如。我有C:/文件夾,有3個JPG文件。我的客戶必須運行。我如何獲得多個jpg。或txt文件從任何文件夾?

Client.cs:也是我server.cs在流中獲取文件

private void btn_send2_Click(object sender, EventArgs e) 
     { 
      string[] paths= null; 

      paths= System.IO.Directory.GetFiles(@"C:\folder" + @"\", "*.jpg", System.IO.SearchOption.AllDirectories); 

      byte[] Dizi; 
      TcpClient Gonder = new TcpClient("127.0.0.1", 51124); 
      FileStream Dosya; 
      FileInfo Dos; 
      NetworkStream Akis; 

      foreach (string path in paths) 
      { 
       Dosya = new FileStream(path , FileMode.OpenOrCreate); 
       Dos = new FileInfo(path); 
       Dizi = new byte[(int)Dos.Length]; 
       Dosya.Read(Dizi, 0, (int)Dos.Length); 
       Akis = Gonder.GetStream(); 
       Akis.Write(Dizi, 0, (int)Dosya.Length); 
       Gonder.Close(); 
       Akis.Flush(); 
       Dosya.Close(); 
      } 
     }

我也有Server.cs

void Dinle() 
     { 
      TcpListener server = null; 
      try 
      { 

       Int32 port = 51124; 
       IPAddress localAddr = IPAddress.Parse("127.0.0.1"); 
       server = new TcpListener(localAddr, port); 
       server.Start(); 
       Byte[] bytes = new Byte[1024 * 250000]; 
       // string ReceivedPath = "C:/recieved"; 


       while (true) 
       { 
        MessageBox.Show("Waiting for a connection... "); 

        TcpClient client = server.AcceptTcpClient(); 
        MessageBox.Show("Connected!"); 

        NetworkStream stream = client.GetStream(); 
        if (stream.CanRead) 
        { 
         saveFileDialog1.ShowDialog(); 

         // burası degişecek 
         string pathfolder = saveFileDialog1.FileName; 
         StreamWriter yaz = new StreamWriter(pathfolder); 

         string satir; 
         StreamReader oku = new StreamReader(stream); 

         while ((satir = oku.ReadLine()) != null) 
         { 


          satir = satir + (char)13 + (char)10; 
          yaz.WriteLine(satir); 

         } 
         oku.Close(); 
         yaz.Close(); 
         client.Close(); 
        } 
       } 
      } 
      catch (SocketException e) 
      { 
       Console.WriteLine("SocketException: {0}", e); 
      } 
      finally 
      { 
       // Stop listening for new clients. 
       server.Stop(); 
      } 


      Console.WriteLine("\nHit enter to continue..."); 
      Console.Read(); 
     }

請看Client.cs:icollected全部來自文件「c:\文件夾」

paths= System.IO.Directory.GetFiles(@"C:\folder" + @"\", "*.jpg", System.IO.SearchOption.AllDirectories);

我的Server.cs如何從流中獲取所有文件?

+0

是它太硬的問題嗎?還是不清楚? – Penguen 2010-05-10 10:03:07

回答

0

這不是一種典型的做事方式。

通常情況下,您會在單個流中編寫單個文件,併爲多個文件重複該過程。這種方式會導致數據損壞,因爲您必須在流中放置某種標記以瞭解將其分割的位置。

0

最簡單的方法是使用多個套接字,一個用於命令,一個(或多個)用於發送文件。

下面的代碼沒有經過測試,只是寫了它來顯示我的意思。它是多線程的,可以從同一個客戶端接收多個文件,只需在客戶端多次調用sendfiles即可。

如果您決定完成代碼,則可能需要添加錯誤/異常處理。

Server.cs

using System; 
using System.IO; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 

namespace Test2 
{ 
    public class Server 
    { 
     private readonly TcpListener _listener = new TcpListener(1234); 

     public void Start() 
     { 
      _listener.BeginAcceptTcpClient(OnClient, null); 
     } 

     private void OnClient(IAsyncResult ar) 
     { 
      // End async accept and start wait for a new connection again 
      TcpClient client = _listener.EndAcceptTcpClient(ar); 
      _listener.BeginAcceptTcpClient(OnClient, null); 

      // Let's start receiving files from the accepted client. 
      var context = new Context {Client = client, Buffer = new byte[8196]}; 
      client.GetStream().BeginRead(context.Buffer, 0, context.Buffer.Length, OnReceive, context); 
     } 

     /// <summary> 
     /// Got some stuff from a client 
     /// </summary> 
     /// <param name="ar"></param> 
     private void OnReceive(IAsyncResult ar) 
     { 
      // got a file command 
      var context = (Context) ar.AsyncState; 
      int bytesRead = context.Client.GetStream().EndRead(ar); 

      string cmd = Encoding.UTF8.GetString(context.Buffer, 0, bytesRead); 
      string[] parts = cmd.Split(';'); 
      string command = parts[0]; 


      // want to send another file 
      if (command == "sendfile") 
      { 
       // context info for receiving files 
       var client = new FileClient(); 
       client.FileName = parts[1]; 
       client.Size = long.Parse(parts[2]); 
       client.FileStream = new FileStream("C:\\" + client.FileName, FileMode.CreateNew, FileAccess.Write); 

       // startup listener where we are going to receive the file. 
       var listener = new TcpListener(IPAddress.Any, 0); // get a kernelassigned number 
       client.Listener = listener; 
       listener.Start(); 
       listener.BeginAcceptTcpClient(OnFileSocket, client); 

       // send reply 
       var ep = (IPEndPoint) listener.LocalEndpoint; 
       byte[] reply = Encoding.UTF8.GetBytes(ep.Port.ToString()); 
       context.Client.GetStream().Write(reply, 0, reply.Length); 
      } 
     } 

     // Receiving the actual files. 
     private void OnFileSocket(IAsyncResult ar) 
     { 
      var client = (FileClient) ar.AsyncState; 
      client.Socket = client.Listener.EndAcceptTcpClient(ar); 

      var buffer = new byte[8192]; 
      client.Buffer = buffer; 
      client.Socket.GetStream().BeginRead(buffer, 0, buffer.Length, OnReceiveFile, client); 
     } 

     private void OnReceiveFile(IAsyncResult ar) 
     { 
      var client = (FileClient) ar.AsyncState; 
      int bytesRead = client.Socket.GetStream().EndRead(ar); 
      client.Received += bytesRead; 

      client.FileStream.Write(client.Buffer, 0, bytesRead); 

      // recieved complete file, disconnect and exit. 
      if (client.Received == client.Size) 
      { 
       client.FileStream.Close(); 
       client.Socket.Close(); 
       return; 
      } 

      client.Socket.GetStream().BeginRead(client.Buffer, 0, client.Buffer.Length, OnReceiveFile, client); 
     } 

     #region Nested type: Context 

     private class Context 
     { 
      public byte[] Buffer; 
      public TcpClient Client; 
     } 

     #endregion 

     #region Nested type: FileClient 

     private class FileClient 
     { 
      public byte[] Buffer; 
      public string FileName; 
      public FileStream FileStream; 
      public TcpListener Listener; 
      public long Received; 
      public long Size; 
      public TcpClient Socket; 
     } 

     #endregion 
    } 
} 

Client.cs

using System; 
using System.IO; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 

namespace Test2 
{ 
    internal class Client 
    { 
     private readonly IPAddress _server; 
     private readonly TcpClient _tcpClient = new TcpClient(); 

     public Client(IPAddress server) 
     { 
      _server = server; 
      _tcpClient = new TcpClient(); 
     } 

     public void Connect() 
     { 
      _tcpClient.Connect(new IPEndPoint(_server, 1234)); 
     } 

     // asks server on which port the file should be sent. 
     private int RequestPort(string fileName, long length) 
     { 
      // lock tpcClient for each request, so we dont mix up the responses. 
      lock (_tcpClient) 
      { 
       // send request 
       byte[] bytes = Encoding.UTF8.GetBytes("sendfile;" + fileName + ";" + length); 
       _tcpClient.GetStream().Write(bytes, 0, bytes.Length); 

       // get reply 
       var buffer = new byte[1024]; 
       int bytesRead = _tcpClient.GetStream().Read(buffer, 0, buffer.Length); 
       string reply = Encoding.UTF8.GetString(buffer, 0, bytesRead); 

       // error message or port? 
       int port; 
       if (!int.TryParse(reply, out port)) 
        throw new InvalidOperationException("Server sent an error:" + reply); 
       return port; 
      } 
     } 

     public void SendFiles(string[] fileNames) 
     { 
      // Use a buffer to not preserve memory (instead of reading whole file into memory) 
      var buffer = new byte[8192]; 
      foreach (string fileName in fileNames) 
      { 
       using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
       { 
        // Send on commandchannel that we want to send a file. 
        int filePort = RequestPort(Path.GetFileName(fileName), fileStream.Length); 
        var client = new TcpClient(new IPEndPoint(_server, filePort)); 
        NetworkStream stream = client.GetStream(); 

        // repeat until there are no more bytes to read. 
        int bytesRead = fileStream.Read(buffer, 0, buffer.Length); 
        while (bytesRead > 0) 
        { 
         stream.Write(buffer, 0, bytesRead); 
         bytesRead = fileStream.Read(buffer, 0, buffer.Length); 
        } 

        stream.Close(); 
        client.Close(); 
       } 
      } 
     } 
    } 
} 
相關問題