我分别使用JNA和Powershell中的客户端在Java中实现了一个简单的双向管道服务器。
基本上,我希望客户端能够连接,向服务器发送消息,最后从服务器获取消息。
实际结果不同。当我先运行服务器然后运行客户端时,客户端永远等待连接,而服务器连接后则等待从管道中读取消息。
下面是服务器的Java代码和客户端的Powershell代码。
有什么办法解决这个问题吗?
谢谢!
static final int MAX_BUFFER_SIZE = 1024;
static String pipeName = "\\\\.\\pipe\\testpipe";
static HANDLE namedPipe;
public static void main(final String[] args) {
createPipe();
runServerFile();
}
private static void createPipe() {
namedPipe = INSTANCE.CreateNamedPipe(pipeName,
WinBase.PIPE_ACCESS_DUPLEX , // dwOpenMode
WinBase.PIPE_TYPE_BYTE | WinBase.PIPE_READMODE_BYTE | WinBase.PIPE_WAIT,// | WinBase.PIPE_READMODE_MESSAGE | WinBase.PIPE_TYPE_MESSAGE, // dwPipeMode
WinBase.PIPE_UNLIMITED_INSTANCES , // nMaxInstances,
//WinBase.PIPE_UNLIMITED_INSTANCES, // nMaxInstances (255),
Byte.MAX_VALUE, // nOutBufferSize,
Byte.MAX_VALUE, // nInBufferSize,
1000, // nDefaultTimeOut,
null); // lpSecurityAttributes
System.out.println("Created pipe: " + namedPipe.toString() + " invalid_handle = " + WinBase.INVALID_HANDLE_VALUE.toString());
System.out.println("Last error: " + Native.getLastError());
}
private static void runServerFile() {
RandomAccessFile npipeClient = null;
try {
System.out.println("br1");
npipeClient = new RandomAccessFile(pipeName, "rws");
INSTANCE.ConnectNamedPipe(namedPipe,null);
byte[] buffer = new byte[100];
int rd_count;
String recv;
System.out.println("Connected pipe");
do{
System.out.println("Before read");
rd_count = npipeClient.read(buffer);
if(rd_count<0) break;
System.out.println("After read");
recv = new String(buffer,0, rd_count);
System.out.println("Received" + recv);
}while(!recv.equalsIgnoreCase("done"));
System.out.println("Received correct message");
//npipeClient.write("Hello world!".getBytes());
npipeClient.writeUTF("Hello back!");
//npipeClient.getFD().sync();
//INSTANCE.FlushFileBuffers(new HANDLE(npipeClient.getFD().));
System.out.println("Sent: Hello back");
npipeClient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
param ($ComputerName = '.')
$npipeClient = new-object System.IO.Pipes.NamedPipeClientStream($ComputerName, 'testpipe', [System.IO.Pipes.PipeDirection]::InOut,
[System.IO.Pipes.PipeOptions]::None,
[System.Security.Principal.TokenImpersonationLevel]::Impersonation)
$pipeReader = $pipeWriter = $null
function WriteToPipeAndLog($msg) {
$msg
$pipeWriter.WriteLine($msg)
}
try {
'Client connecting to sever'
$npipeClient.Connect()
'Connected to server'
$pipeReader = new-object System.IO.StreamReader($npipeClient)
$pipeWriter = new-object System.IO.StreamWriter($npipeClient)
$pipeWriter.AutoFlush = $true
Write-Host "Sent: Hello world!"
$pipeWriter.WriteLine('Hello world!')
$pipeWriter.WriteLine('How ya doing')
$pipeWriter.WriteLine('Done')
while (($line = $read.ReadLine()) -ne $null)
{
Write-Host "Received: " $line
}
}
finally {
'Client exiting'
$npipeClient.Dispose()
}