我希望有人可以解释这种行为,或者它可能是.NET中的错误。

由于夏时制而使时间向后移动,这意味着NetworkStream无需注意其属性ReadTimeout,并且在此代码的情况下,将导致循环旋转。 (这只是证明它正在发生的一个例子)。

要重现我看到的问题,您需要将其设置为使用夏时制的时区,例如英国。

  • 将您的TimeZone设置为UTC London,并确保选中夏令时。
  • 将日期更改回2017年10月29日
  • 将您的时间设置为01:58:50 am
  • 运行以下代码,并在将夏令时应用于凌晨2点时观看旋转,如果正确应用夏令时,则时间应移回到凌晨1点。
  • 请确保您等待,它可能需要30秒才能开始旋转。

  • 编辑:经过深入调查后,在1个小时后,它停止旋转,行为恢复正常并接受ReadTimeout。

    任何想法将不胜感激!

    客户代码:
    class Program
    {
        static bool running = false;
    
        static void Main(string[] args)
        {
            running = true;
            Task.Factory.StartNew(() => Run());
    
            Console.ReadKey();
    
            running = false;
        }
    
    
        static void Run()
        {
            TcpClient connection = new TcpClient("127.0.0.1", 1234);
    
            while (running)
            {
                if (connection != null && connection.Connected)
                {
                    try
                    {
                        NetworkStream stream = connection.GetStream();
                        stream.ReadTimeout = 1000;
    
                        byte[] buffer = new byte[1024];
                        int readCount = stream.Read(buffer, 0, 1024); // Should block here for the ReadTimeout duration if nothing received
                                                                      // However when daylight savings is applied and time moves backwards an hour, the stream.ReadTimeout = 1000;
                                                                      // is not honoured and it falls through and spins
    
                        if (readCount > 0)
                        {
                            Console.WriteLine("Received some data");
                            //process read here
                        }
                        else
                        {
                            Console.WriteLine("ReadTimeout was not honoured");
                        }
                    }
                    catch (IOException)
                    {
                        Console.WriteLine("Read timed out");
                    }
                }
            }
        }
    }
    

    服务器代码:
    class Program
        {
            static bool running = false;
    
            public static void Main()
            {
                TcpListener server = null;
                try
                {
                    // Set the TcpListener on port 13000.
                    Int32 port = 5000;
                    IPAddress localAddr = IPAddress.Parse("192.168.1.69");
    
                    // TcpListener server = new TcpListener(port);
                    server = new TcpListener(localAddr, port);
    
                    // Start listening for client requests.
                    server.Start();
    
                    // Enter the listening loop.
                    while (true)
                    {
                        Console.Write("Waiting for a connection... ");
    
                        // Perform a blocking call to accept requests.
                        // You could also user server.AcceptSocket() here.
                        TcpClient client = server.AcceptTcpClient();
                        Console.WriteLine("Connected!");
    
    
                        // Get a stream object for reading and writing
                        NetworkStream stream = client.GetStream();
    
                        running = true;
    
                        Task.Factory.StartNew(() => Run(stream));
    
    
                        Console.ReadKey();
    
                        // Shutdown and end connection
                        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();
            }
    
            static async Task Run(NetworkStream stream)
            {
                byte[] stuffToSend = Encoding.ASCII.GetBytes("Stuff to send");
                while (running)
                {
                    stream.Write(stuffToSend, 0, stuffToSend.Length);
                    await Task.Delay(1000);
                }
            }
        }
    

    最佳答案

    .NET ReadTimeout属性中未提及the OS documentation中有一些非常重要的注释:



    当前,每次超时后,您都在循环并尝试在同一套接字上进行另一个接收操作。但是,此注释非常清楚,您需要创建一个新的连接。

    10-05 23:32