2

我正在用 C# 开发一个服务器应用程序。客户端可以连接到服务器并发出各种请求。目前,当客户端连接时,我会生成一个新线程来处理请求。我正在使用 TCPClient 类来处理客户端连接。我的服务器工作如下:

  1. 客户端通过请求连接到服务器
  2. 服务器处理请求
  3. 服务器等待查看客户端是否有更多请求
  4. 如果客户端在某个超时时间内没有发出另一个请求,服务器将终止连接

我的问题如下:

当我从 TCPClient 类获得的 NetworkStream 对象中读取数据时,如果没有可用的数据,则 NetworkStream Read() 方法不会阻塞。当服务器到达第 3 步时,我想在 NetworkStream 上设置一些超时,如果客户端在此期间没有发出任何请求,则服务器应该在抛出超时异常时终止连接。当我的服务器到达第 3 步时,NetworkStream Read() 方法不会阻塞,不管我将它的 ReadTimeout 属性设置为什么。任何人都可以帮助我,或者建议一种更好的方法来做我想做的事情。

谢谢

4

6 回答 6

2

如果没有数据要读取,NetworkStream.Read 和 ReadByte 应该阻塞直到超时。我认为呼叫更有可能正在读取某些内容,可能是一堆零。仔细检查客户端发送的数据。

于 2009-07-29T18:38:05.447 回答
0

这是你要找的吗?

http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.receivetimeout.aspx

看起来您使用 GetStream() 从 TcpClient 获取 NetworkStream,然后对其调用 Read() 方法。

于 2009-07-29T19:00:24.457 回答
0

将 NetworkStream 包装在 BufferedStream 中。BufferedStream.Read 将阻塞直到至少 1 个字节可用。

于 2009-07-27T19:55:34.053 回答
0

您应该从使用 Read() 过渡到BeginRead()方法并研究并行处理。网络编程不适合胆小的人。

基本上,您不想为数据创建循环轮询。

while(!timedout && !stream.DataAvailable) sleep(0); // This is bad.
if(steam.DataAvailable) steam.Read();

相反,做这样的事情更有意义。创建重置事件,调用 BeginRead(),并在回调中释放重置事件。类似于以下内容:

void clientThread()
{
   stream.BeginRead(myCallback);
   resetEvent.WaitOne(timeout)
}
void myCallback
{
   resetEvent.Set();
}
于 2009-07-27T18:53:11.980 回答
0

要在没有可用数据时显式强制 NetworkStream 阻塞:

TcpClient clientConnection = new TcpClient();

if(clientConnection.Available > 0)
{ 
  //You want to continue execution even though there is no available data to be read from the server then:
  clientConnection.Client.Blocking = false;
}
于 2016-10-31T11:32:02.427 回答
-1

您需要自己处理“超时”,因为 NetworkStream.Read() 没有提供这样做的方法。

您可能想要在客户端线程中执行的操作是结合使用 NetworkStream.DataAvailable 和/或 NetworkStream.CanRead 与阻塞/超时机制(例如使用带有超时的 WaitHandle.WaitOne 调用)来提供客户有时间提供数据。如果在指定时间后没有任何内容,只需关闭连接并退出。

于 2009-07-27T18:55:53.753 回答