Как Вы отправляете строку именованного канала от неуправляемого до пространства управляемого кода?

У меня, кажется, есть именованные каналы 101 проблема. У меня есть очень простой набор для соединения симплексной передачи именованного канала от C++, неуправляемое приложение к C# управляло приложением. Подключения канала, но я не могу отправить "сообщение" через канал, если я не закрываю дескриптор, который, кажется, сбрасывает буфер и передает сообщение через. Это похоже на сообщение, заблокирован. Я попытался инвертировать роли клиента/сервера и вызвать их с различными комбинациями Флага без любой удачи. Я могу легко отправить сообщения в другом направлении от C#, управляемого к неуправляемому C++. Делает у любого есть любое понимание. Может какой-либо из Вас, парни успешно отправляют сообщения от C++, неуправляемого к управляемому C#? Я могу найти много примеров intra amanged или неуправляемых каналов, но не предать земле управляемый к/от unamanged - просто утверждает, что смог сделать это.

В списках я опустил большую часть материала обертки для ясности. Ключевые биты я верю этому, релевантны, соединение/создание/чтение канала и методы записи. Не волнуйтесь слишком много о блокировании/поточной обработке здесь.

Сторона сервера C#

    // This runs in its own thread and so it is OK to block
    private void ConnectToClient()
    {
        // This server will listen to the sending client
        if (m_InPipeStream == null)
        {
            m_InPipeStream =
                new NamedPipeServerStream("TestPipe", PipeDirection.In, 1);
        }

        // Wait for client to connect to our server
        m_InPipeStream.WaitForConnection();

        // Verify client is running
        if (!m_InPipeStream.IsConnected)
        {
            return;
        }

        // Start listening for messages on the client stream
        if (m_InPipeStream != null && m_InPipeStream.CanRead)
        {
            ReadThread = new Thread(new ParameterizedThreadStart(Read));
            ReadThread.Start(m_InPipeStream);
        }
    }


    // This runs in its own thread and so it is OK to block
    private void Read(object serverObj)
    {
        NamedPipeServerStream pipeStream = (NamedPipeServerStream)serverObj;
        using (StreamReader sr = new StreamReader(pipeStream))
        {
            while (true)
            {
                string buffer = "" ;
                try
                {
                    // Blocks here until the handle is closed by the client-side!!
                    buffer = sr.ReadLine();   // <<<<<<<<<<<<<<  Sticks here
                }
                catch
                {
                    // Read error
                    break;
                }

                // Client has disconnected?
                if (buffer == null || buffer.Length == 0)
                    break;

                // Fire message received event if message is non-empty
                if (MessageReceived != null && buffer != "")
                {
                    MessageReceived(buffer);
                }
            }
        }
    }

Сторона клиента C++

    // Static - running in its own thread.
    DWORD CNamedPipe::ListenForServer(LPVOID arg)
    {
        // The calling app (this) is passed as the parameter
        CNamedPipe* app = (CNamedPipe*)arg;

        // Out-Pipe: connect as a client to a waiting server
        app->m_hOutPipeHandle =
        CreateFile("\\\\.\\pipe\\TestPipe",
               GENERIC_WRITE,
               0,
               NULL,
               OPEN_EXISTING,
               FILE_ATTRIBUTE_NORMAL,
               NULL);
        // Could not create handle
        if (app->m_hInPipeHandle == NULL ||
            app->m_hInPipeHandle == INVALID_HANDLE_VALUE)
        {
            return 1;
        }

        return 0;
    }


    // Sends a message to the server
    BOOL CNamedPipe::SendMessage(CString message)
    {
    DWORD dwSent;

        if (m_hOutPipeHandle == NULL ||
            m_hOutPipeHandle == INVALID_HANDLE_VALUE)
        {
            return FALSE;
        }
        else
        {
            BOOL bOK =
                WriteFile(m_hOutPipeHandle,
                          message, message.GetLength()+1, &dwSent, NULL);
            //FlushFileBuffers(m_hOutPipeHandle);             // <<<<<<< Tried this
            return (!bOK || (message.GetLength()+1) != dwSent) ? FALSE : TRUE;
        }
    }


    // Somewhere in the Windows C++/MFC code...
    ...
    // This write is non-blocking. It just passes through having loaded the pipe.
    m_pNamedPipe->SendMessage("Hi de hi");
    ...
8
задан user320240 8 June 2010 в 15:16
поделиться

1 ответ

sr.ReadLine() ожидает увидеть символ(ы) новой строки, чтобы узнать конец строки. Поскольку он не получает ни новой строки, ни конца строки, он ожидает большего. Попробуйте:

m_pNamedPipe->SendMessage("Hi de hi\n")

или некоторые из методов sr.Read().

10
ответ дан 5 December 2019 в 17:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: