我正在从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 :(得分:3)
Mark的答案后续跟进......我使用这种方法,您应该很容易看到如何合并它。
/// <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;
}
答案 1 :(得分:2)
读取/接收应该在循环中使用,直到您获得EOF(零字节读取)或您期望的数据量(使用成帧API)。您当前的代码无效:即使发送了483628个字节,单个字节也是在单次调用Read中返回的合法数量。
答案 2 :(得分: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);
}
}