四、读写数据
从命名管道读数据时我们不能提前知道消息的长度。我们的解决方案不需要处理很长的消息,所以使用System.Int32变量来指定消息的长度。
NamedPipeWrapper.WriteBytes 方法可以将消息写到一个命名管道,消息按UTF8编码,然后按字节数组传递。
public static void WriteBytes(PipeHandle handle, byte[]bytes) {
byte[] numReadWritten = new byte[4];
uint len;
if(bytes==null){
bytes=newbyte[0];
}
if (bytes.Length == 0) {
bytes = new byte[1];
bytes = System.Text.Encoding.UTF8.GetBytes(" ");
}
// 获取消息的长度:
len= (uint)bytes.Length;
handle.State = InterProcessConnectionState.Writing;
// 获取消息长度的字节表示,先写这四字节
if(NamedPipeNative.WriteFile(handle.Handle,BitConverter.GetBytes(len),4,numReadWritten,0)){
// 写余下的消息
if(!NamedPipeNative.WriteFile(handle.Handle,bytes,len,numReadWritten,0)){
handle.State=InterProcessConnectionState.Error;
thrownewNamedPipeIOException("Errorwritingtopipe. Internalerror:"+NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError());
}
}
else{
handle.State=InterProcessConnectionState.Error;
thrownewNamedPipeIOException("Errorwritingtopipe.Internalerror:"+NamedPipeNative.GetLastError().ToString(),
NamedPipeNative.GetLastError());
}
handle.State =InterProcessConnectionState.Flushing;
// 激活管道,保证任何缓存数据都被写入管道,不会丢失:
Flush(handle);
handle.State = InterProcessConnectionState.FlushedData;
}
要从一个命名管道读数据,先要把前四个字节转化为整数以确定消息的长度。接着,就可以读余下的数据了,请看下面的NamedPipeWrapper.ReadBytes方法。
public static byte[] ReadBytes(PipeHandle handle, int maxBytes) {
byte[]numReadWritten=newbyte[4];
byte[]intBytes=newbyte[4];
byte[]msgBytes=null;
intlen;
handle.State=InterProcessConnectionState.Reading;
handle.State=InterProcessConnectionState.Flushing;
// 读前四个字节并转化为整数:
if(NamedPipeNative.ReadFile(handle.Handle, intBytes,4, numReadWritten, 0)) {
len=BitConverter.ToInt32(intBytes,0);
msgBytes=newbyte[len];
handle.State=InterProcessConnectionState.Flushing;
// 读余下的数据或抛出异常:
if(!NamedPipeNative.ReadFile(handle.Handle,msgBytes,(uint) len,numReadWritten,0)){
handle.State=InterProcessConnectionState.Error;
thrownewNamedPipeIOException("Error readingfrompipe. Internalerror:"+NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError());
}
}
else {
handle.State=InterProcessConnectionState.Error;
thrownewNamedPipeIOException("Errorreadingfrompipe. Internalerror:"+NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError());
}
handle.State=InterProcessConnectionState.ReadData;
if(len>maxBytes){
returnnull; }
returnmsgBytes;
}
以上就是命名管道的实现和一些主要的方法,下面介绍如何创建进行文本消息通信的命名管道服务器和客户端应用程序。
