簡體   English   中英

C ++和Java應用程序之間的NamedPipe進程間

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM