Это продолжение вопроса this . Я новичок в сетевом программировании, поэтому я просто пишу небольшие примеры, чтобы понять, но немного пытаюсь объяснить результаты.
Кажется, настройка NetworkStream.ReceiveTimeout
работает неправильно, когда клиент, который должен был отправлять данные, просто закрывается перед отправкой всех ожидаемых данных.
Вот пример кода:
public static void Main(string[] args)
{
TcpListener listener = new TcpListener(IPAddress.Any, 10001);
listener.Start();
ThreadPool.QueueUserWorkItem(WriterThread);
using (TcpClient client = listener.AcceptTcpClient())
using (NetworkStream stream = client.GetStream())
{
client.ReceiveTimeout = (int)new TimeSpan(0, 0, 2).TotalMilliseconds;
stream.ReadTimeout = (int)new TimeSpan(0, 0, 2).TotalMilliseconds;
ReceiveMessage(stream, 1024);
}
listener.Stop();
Console.WriteLine("Done.");
Console.ReadKey(true);
}
private static void WriterThread(object state)
{
using (TcpClient client = new TcpClient())
{
client.Connect(new IPEndPoint(IPAddress.Loopback, 10001));
using (NetworkStream stream = client.GetStream())
{
byte[] bytes = Encoding.ASCII.GetBytes("obviously less than 1024 bytes");
stream.Write(bytes, 0, bytes.Length);
Thread.Sleep(10000); // comment out
}
}
}
private static byte[] ReceiveMessage(Stream stream, int length)
{
byte[] buffer = new byte[length];
int bufferFill = 0;
while (true)
{
bufferFill += stream.Read(buffer, bufferFill, buffer.Length - bufferFill);
if (buffer.Length == bufferFill)
return buffer;
Thread.Sleep(100);
}
}
Эта версия работает правильно, вызывая исключение при вызове stream.Read()
. Однако, если я закомментирую Thread.Sleep(10000)
, клиент закрывает соединение, но слушатель не может его распознать. Основной поток застревает внутри цикла while(true)
. stream.Read()
продолжает возвращать ноль, но исключение не выдается.
Это нормально? Если да, как я могу справиться с ненормальным отключением клиента?