Mam sobie taką funkcję do czytania danych z NetworkStream
/// <summary>
/// Reads data from network stream
/// </summary>
/// <param name="ns">NetworkStream from which data is to be read </param>
/// <returns>data read from NetworkStream</returns>
#region ReadBuffer
private string ReadBuffer(NetworkStream ns)
{
byte[] buffer = new byte[1024];
int i = 0;
int b;
int timeout = System.Environment.TickCount;
try
{
// wait for data to show up on the stream
while (!ns.DataAvailable && ((System.Environment.TickCount - timeout) < 20000))
{
System.Threading.Thread.Sleep(100);
}
if (!ns.DataAvailable)
{
//throw new Exception("No response received from server.");
AddLogMessage("No response received from server.");
}
// read while there's data on the stream
while (i < buffer.Length && ns.DataAvailable)
{
b = ns.ReadByte();
buffer[i++] = (byte)b;
}
}
catch (System.IO.IOException)
{
// error reading from stream
//throw new Exception("Error receiving data from server.");
AddLogMessage("Error receiving data from server.");
}
return Encoding.ASCII.GetString(buffer);
}
#endregion
i wszystko jest fajnie jeśli dane nie przekraczają wartości 1024 bajtów (byte[] buffer = new byte[1024];). Ale jeśli chcę odczytać coś większego - np: treść maila pobieranego z serwera - to on już przekracza 1024 bajty i dostaje tylko kawałem zawartości. Pomyślałem sobie, że można dynamicznie sprawdzać rozmiar danych po tym jak trafiłem na pole Lenght. Pogmerałem w necie i znalazłem f-cję do zmiany rozmiaru tablicy bajtów:
<code class="c#">
public byte [] ReDim(byte [] array, int newSize)
{
byte [] abytNew = new byte[newSize];
Buffer.BlockCopy(array, 0, abytNew, 0, newSize);
return abytNew;
}
i odpowiednio zmodyfikowałem kod f-cji ReadBuffer:
#region ReadBuffer
/// <summary>
/// Reads data from network stream
/// </summary>
/// <param name="ns">NetworkStream from which data is to be read </param>
/// <returns>data read from NetworkStream</returns>
private string ReadBuffer(NetworkStream ns)
{
byte[] buffer = new byte[1024];
int i = 0;
int b;
int timeout = System.Environment.TickCount;
try
{
// wait for data to show up on the stream
while (!ns.DataAvailable && ((System.Environment.TickCount - timeout) < 20000))
{
System.Threading.Thread.Sleep(100);
}
if (!ns.DataAvailable)
{
//throw new Exception("No response received from server.");
AddLogMessage("No response received from server.");
}
// read while there's data on the stream
while (i < buffer.Length && ns.DataAvailable)
{
if (ns.Length >= buffer.Length)
{
buffer = ReDim(buffer, (int)ns.Length);
}
b = ns.ReadByte();
buffer[i++] = (byte)b;
}
}
catch (System.IO.IOException)
{
// error reading from stream
//throw new Exception("Error receiving data from server.");
AddLogMessage("Error receiving data from server.");
}
return Encoding.ASCII.GetString(buffer);
}
#endregion
Kompilacja przechodzi gładko (beż żadnych błędów czy ostrzeżeń). Ale w czasie wykonywania program rzuca takim wyjątkiem:
> System.NotSupportedException: Ten strumień nie obsługuje operacji szukania.
> at System.Net.Sockets.NetworkStream.get_Length
> at Emilia.MainForm.ReadBuffer in f:\Projects\Emilia.NET\Emilia\MainForm.cs:line 112
> at Emilia.MainForm.Button1Click in f:\Projects\Emilia.NET\Emilia\MainForm.cs:line 167
> at System.Windows.Forms.Control.OnClick
> at System.Windows.Forms.Button.OnClick
> at System.Windows.Forms.Button.OnMouseUp
> at System.Windows.Forms.Control.WmMouseUp
> at System.Windows.Forms.Control.WndProc
> at System.Windows.Forms.ButtonBase.WndProc
> at System.Windows.Forms.Button.WndProc
> at ControlNativeWindow.OnMessage
> at ControlNativeWindow.WndProc
> at System.Windows.Forms.NativeWindow.DebuggableCallback
> at ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop
> at ThreadContext.RunMessageLoopInner
> at ThreadContext.RunMessageLoop
> at System.Windows.Forms.Application.Run
> at Emilia.Program.Main in f:\Projects\Emilia.NET\Emilia\Program.cs:line 37
Czyli wychodzi na to, że nie można zdefiniować ile danych zawiera ten strumień... Może mi ktoś podpowiedzieć jak to zrealizować ?