【发布时间】:2014-06-05 17:35:37
【问题描述】:
在 c# 中,我有一个非常简单的服务器/客户端。客户端在接收时设置为超时 500 毫秒。当它超时时,我希望它会抛出一个异常,但是,我会在 500 毫秒后捕获它,总共达到一秒。为了仔细检查我是否只有一台慢速机器,我测试了抛出异常需要多长时间,它是正确的。这里有一些sn-ps。
服务器线程:
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));
}
}
有人遇到过这样的问题吗?
【问题讨论】:
-
我怀疑可能有某种协议交换触发了超时重置。您是否尝试过通过管道发送数据,进行接收以获取该数据,然后查看第二次接收的超时时间是多少?
-
连接后是否检查了ReceiveTimeout属性的值?
-
我添加了您的其他建议,但不幸的是它仍然在 1 秒后失败。