命名管道服务器读取超时
本文关键字:读取 超时 服务器 管道 | 更新日期: 2023-09-27 18:02:32
当使用c# NamedPipeServerStream时,如果客户端没有发送任何消息结束模式(如服务器读取ReadLine()时的'r'n) NamedPipeServerStream读取方法将永远等待,并且没有Abort()或interrupt()方法将在该线程上工作。
以来:
1)流。NamedPipeServerStream不支持ReadTimeout
2) Abort()或interrupt()在线程上不起作用
NamedPipeServerStream.Disconnect()不工作
目前还不清楚,如何在NamedPipeServerStream读取操作上设置超时?
让我来介绍一个例子。我们的IPC规范要求交换以0结尾的字符串。客户端发送消息,服务器处理消息并作为"必须"发送响应。如果客户端最终没有发送'0(客户端不是我们的,所以我们不能保证它的工作正确性),Read方法将永远等待,客户端(因为我们不控制它)也可能永远等待响应。
下面是一个简化的实现示例:
public void RestartServer()
{
_pipeServerThread.Interrupt(); //doesn't affect Read wait
_pipeServerThread.Abort(); //doesn't affect Read wait
}
private void PipeServerRun(object o) //runs on _pipeServerThread
{
_pipeServer = new NamedPipeServerStream(_pipeName, InOut, 100,
PipeTransmissionMode.Message, PipeOptions.WriteThrough);
//_pipeServer.ReadTimeout = 100; //System.InvalidOperationException: Timeouts are not supporte d on this stream.
// Wait for a client to connect
while (true)
{
_pipeServer.WaitForConnection();
string request = ReadPipeString();
//... process request, send response and disconnect
}
}
/// <summary>
/// Read a '0 terminated string from the pipe
/// </summary>
private string ReadPipeString()
{
StringBuilder builder = new StringBuilder();
var streamReader = new StreamReader(_pipeServer);
while (true)
{
//read next byte
char[] chars = new char[1];
streamReader.Read(chars, 0, 1); // <- This will wait forever if no '0 and no more data from client
if (chars[0] == ''0') return builder.ToString();
builder.Append(chars[0]);
}
}
那么如何在NamedPipeServerStream读取操作上设置超时?
由于您正在以消息模式运行管道,因此您应该首先将整个消息读入byte[]
缓冲区或内存流,然后决定它是否有效并解码它。管道消息具有确定的长度。它不能显式检索,但当您从消息模式管道读取时,它会显示出来。如果消息中仍有未读字节,则Win32 ReadFile
与ERROR_MORE_DATA
一起失败,然后返回TRUE
以指示消息结束。在此之后,对ReadFile
的调用将阻塞,直到有新消息可用。StreamReader
自然不知道这些,阻塞你的线程。
Update:实现超时,使用异步I/O (Stream.BeginRead
)。StreamReader
不直接支持。如果你绝对必须使用它,写一个包装器流,它将在底层流上根据BeginRead
实现Read
,并支持超时,取消等。
尝试设置NamedPipeServerStream。ReadMode和/或。transmissionmode转换为Byte。无论如何,你应该使用NamedPipeServerStream的BeginRead/EndRead方法。这样,您就可以自己实现超时逻辑。