簡體   English   中英

套接字接收超時引發延遲的異常

[英]Socket receive timeout throws a delayed exception

在C#中,我有一個非常簡單的服務器/客戶端。 客戶端設置為在接收到500毫秒時超時。 當它超時時,我希望它會引發異常,但是確實會發生,但是,我在500毫秒后捕獲了它,總計總計一秒。 為了再次檢查也許我的計算機速度較慢,我測試了拋出異常大約需要正確的時間。 這是一些片段。

服務器線程:

void ServerThreadProc()
{
    using (Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
    {
        server.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345));
        server.Listen(10);
        using (Socket accepted = server.Accept())
        {
            // Wait so long that client times out.
            System.Threading.Thread.Sleep(5000);
            accepted.Shutdown(SocketShutdown.Both);
            accepted.Close();
        }
    }
}

測試接收超時(失敗):

public void ShouldNotExceedConnectionTime()
{
    Thread s = new Thread(ServerThreadProc);
    s.Start();
    using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
    {
        client.ReceiveTimeout = 500;
        client.Connect("127.0.0.1", 12345);
        byte[] buf = new byte[16];
        System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
        try
        {
            watch.Start();
            client.Receive(buf);
        }
        catch (SocketException ex)
        {
            watch.Stop();
            Assert.That(ex.SocketErrorCode, Is.EqualTo(SocketError.TimedOut));
            Assert.That(watch.ElapsedMilliseconds, Is.AtLeast(475).And.AtMost(525));
        }
    }
    Assert.Fail("Should throw when timeout expired");
}

測試結果:

結果信息

預期:大於或等於475且小於或等於525

但當時是:1000

測試拋出異常(通過):

public void ThrowsInTime()
{
    System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
    try
    {
        watch.Start();
        System.Threading.Thread.Sleep(500);
        throw new Exception("Sleeping is done.");
    }
    catch(Exception)
    {
        watch.Stop();
        Assert.That(watch.ElapsedMilliseconds, Is.AtLeast(475).And.AtMost(525));
    }
}

有人看到這樣的問題嗎?

接收超時的基礎winsock實現有多個引用( 此處此處 ),可能無法按預期工作。 實際上,它可以實現為大約500毫秒加上ReceiveTiemout屬性的值。 嘗試將ReceiveTimeout設置為不同的值,並查看超時是否實際上是500ms +屬性值。 如果是這種情況,那么您將需要在預期的超時計算中考慮額外的500毫秒。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM