![](/img/trans.png)
[英]Interprocess Communication between C++ app and Java App in Windows OS environment
[英]NamedPipe interprocess between c++ and Java application
我需要從c ++端啟動一個命名管道服務器,並獲取一個Java應用程序以從管道讀取數據。
對於創建管道的C ++端,我遵循了MSDN上的示例: https : //msdn.microsoft.com/zh-cn/library/windows/desktop/aa365603(v= vs.85) .aspx
從Java端開始,我做了一段hacky代碼來測試:
Thread readerThread = new Thread( new Runnable()
{
@Override
public void run()
{
String line = null;
while( true )
{
try
{
final RandomAccessFile pipe =
new RandomAccessFile( "\\\\\\\\.\\\\pipe\\\\smarts_interprocess", "r" );
while( null != ( line = pipe.readLine() ) )
{
s_logger.warning( line );
}
}
catch( IOException ex )
{
s_logger.severe( ex.getMessage() );
try
{
Thread.sleep( 1000 );
}
catch( InterruptedException e )
{
s_logger.info( "nothing available, I will sleep for a second" );
}
}
}
}
} );
readerThread.start();
C ++附加代碼:
void Pipe::startMessageLoop()
{
DWORD dwWait{};
BOOL fSuccess;
fPendingIO = ConnectToNewClient(m_inputHandle, &oOverlap_);
while (true)
{
dwWait = ::WaitForSingleObject(oOverlap_.hEvent, INFINITE);
if (dwWait == WAIT_FAILED)
{
::CloseHandle(oOverlap_.hEvent);
std::cout << "failed to WaitForSingleObject.." << std::endl;
}
if (fPendingIO)
{
DWORD cbRet;
fSuccess = GetOverlappedResult(
m_inputHandle, // handle to pipe
&oOverlap_, // OVERLAPPED structure
&cbRet, // bytes transferred
FALSE); // do not wait
switch (dwState)
{
// Pending connect operation
case CONNECTING_STATE:
if (!fSuccess)
{
printf("Error %d.\n", GetLastError());
return;
}
dwState = WRITING_STATE;
break;
// Pending write operation
case WRITING_STATE:
if (!fSuccess)
{
DisconnectAndReconnect();
continue;
}
break;
default:
{
printf("Invalid pipe state.\n");
return;
}
}
}
std::string message = "naive message from server";
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring data = converter.from_bytes(message.c_str());
DWORD numBytesWritten = 0;
switch (dwState)
{
case WRITING_STATE:
fSuccess = WriteFile(
m_inputHandle, // handle to our outbound pipe
data.c_str(), // data to send
wcslen(data.c_str()) * sizeof(wchar_t), // length of data to send (bytes)
&numBytesWritten, // will store actual amount of data sent
NULL // not using overlapped IO
);
// FlushFileBuffers(m_inputHandle);
// The write operation completed successfully.
if (fSuccess)
{
fPendingIO = FALSE;
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
dwState = WRITING_STATE;
continue;
}
// The write operation is still pending.
if (!fSuccess && (GetLastError() == ERROR_IO_PENDING))
{
fPendingIO = TRUE;
continue;
}
// An error occurred; disconnect from the client.
DisconnectAndReconnect();
break;
default:
{
printf("Invalid pipe state.\n");
return;
}
}
}
}
它可以連接到管道,沒有任何問題,但是唯一的問題是,在C ++進程完成之前,Java端無法獲取在c ++端上編寫的數據(終止VS的調試程序是我的意思)。
只要我的C ++進程仍在運行,它就會掛在readLine的位置:line = pipe.readLine()
有人對此有任何想法嗎?
據我所知-如果您在服務器端使用了完全相同的MSDN代碼-服務器在將任何內容寫入管道之前都在等待輸入。 如果您的客戶端從不發送任何內容,則pipe.readLine
將阻塞,直到斷開連接為止。
Java不是我的事,但我猜測服務器的響應還必須包含換行符,以便readLine
返回。
如果您在readLine()
被阻止,則對等方不會發送行。 當對等方退出時,其解除阻塞的原因是讀取器遇到流的末尾,並返回到目前為止接收到的數據。
您需要找出對等方正在發送的內容,並使用適當的讀取方法。 顯然,這不是行,因此readLine()
是完成此工作的錯誤工具。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.