2012-12-11 51 views
0

我正在从tcp流中读取 - 我用“MLSD”命令(检索文件/目录信息)查询了FTP服务器。尽管由于响应大小是可变的(取决于文件/目录等的数量),我不确定“缓冲区”应该设置多少个字节。如何确保通过tcp流从FTP服务器检索所有数据?确定缓冲区应该有多大

private string controlListener(int controlPort) 
     { 
      try 
      { 
       // Create a TcpClient. 
       // Note, for this client to work you need to have a TcpServer 
       // connected to the same address as specified by the server, port 
       // combination. 
       controlClient = new TcpClient(ftpHost, controlPort); 

       // Get a client stream for reading and writing. 
       controlStream = controlClient.GetStream(); 

        // Because we don't know how many bytes are incoming for welcome message - we use a 2 second delay to retrieve all bytes within that time frame. 
        // Receive the TcpServer.response. 
        // Buffer to store the response bytes. 
        Byte[] data = new Byte[4096]; 

        // String to store the response ASCII representation. 
        String responseData = String.Empty; 

        // Get Control Stream Responce: Read the first batch of the TcpServer response bytes. 
        Int32 bytes = controlStream.Read(data, 0, data.Length); 
        responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes); 
        Console.WriteLine(responseData); 

        return responseData; 
      } 
+0

缓冲的要点是,如果你做得很好(你做得不对),你会成功读取整个流,而不管缓冲区大小。缓冲区只会影响使用的内存量,并可能影响应用程序的性能。 – Servy

回答

2

读/接收应该在一个循环中使用,无论是读书,直到你得到一个EOF(零个字节读取),或者你正期待(使用取景API)的数据量。您当前的代码无效:即使发送了483628个字节,单个字节也是合法的数量,只需一次调用Read即可返回。

1

我用这个...

 public static byte[] readFullStream(Stream st, Int32 BufferSize) 
     { 
      try 
      { 
       Monitor.Enter(_lock); 
       byte[] buffer = new byte[BufferSize]; 
       Int32 bytesRead; 
       MemoryStream ms = new MemoryStream(); 
       bool finished = false; 
       while (!finished) 
       { 
        bytesRead = st.Read(buffer, 0, buffer.Length); 
        if (bytesRead > 0) 
        { 
         ms.Write(buffer, 0, bytesRead); 
        } 
        else 
        { 
         finished = true; 
        } 
       } 
       return ms.ToArray(); 
      } 
      finally 
      { 
       Monitor.Exit(_lock); 
      } 
     } 
2

在后续马克的回答......我用这个方法,你应该很容易地看到如何将它。

/// <summary> 
    /// Read TCP response, this simple method can be re-used elsewhere as needed later. 
    /// </summary> 
    /// <returns></returns> 
    private static string ReadResponse(NetworkStream networkStream) 
    { 
     // Check to see if this NetworkStream is readable. 
     if (networkStream.CanRead) 
     { 
      var myReadBuffer = new byte[256]; // Buffer to store the response bytes. 
      var completeMessage = new StringBuilder(); 

      // Incoming message may be larger than the buffer size. 
      do 
      { 
       var numberOfBytesRead = networkStream.Read(myReadBuffer, 0, myReadBuffer.Length); 
       completeMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead)); 
      } while (networkStream.DataAvailable); 

      return completeMessage.ToString(); 
     } 
     return null; 
    }