Is there a way to format EndRead(ar)?

51 Views Asked by At

I would like to process data via a NamedPipeServer. To the server 1000 data are passed as string with content "int, double, bool, string, ...". The int Value increases from 1 -1000; double, bool and string also change. In total, 15 values are passed in one line.

The received data should be read out in the server and converted from string to int,double, bool. My program is functional in this respect.

My problem is that the conversion of the data becomes erroneous if the method "EndRead(ar);" is not synchronous. The sent string is then read multiple times. EndRead then does not recognize the end of the line. Is there a way to force EndRead?

private void BackgroundInit()
{
    _currentServer.WaitForConnection();   //Wait for a client connection
    ClientMessage cm = new ClientMessage  //Create a new message object
    {
        buffer = new byte[1024]       //Set the receive buffer
    };
    _currentServer.BeginRead(cm.buffer, 0, cm.buffer.Length, new AsyncCallback(ReadStream), cm);         }

private async void ReadStream(IAsyncResult ar)
{
    ClientMessage cmo = (ClientMessage)ar.AsyncState;  //Get the message object
    if (_currentServer == null) return;
    int recv = _currentServer.EndRead(ar);    
     //Receive data ==> Fail at 81 - 85


     if (recv > 0) //If data received
    {
    //Convert msg to string
    byte[] read = new byte[recv];
        Buffer.BlockCopy(cmo.buffer, 0, read, 0, recv);
        string message = Encoding.Unicode.GetString(read);

    Array.Clear(cmo.buffer, 0, cmo.buffer.Length);//Free the byte array

        if (_currentServer != null)
    {
         _currentServer.BeginRead(cmo.buffer, 0, cmo.buffer.Length, new AsyncCallback(ReadStream), cmo);
         }

}

Example ==> Message 81 to 85 are faulty

Passing \r\n is not successful. Adjusting the Buffer_Size did not bring any improvement either. The subsequent formatting of the received strings is not possible because the non-synchronous part of the data is skipped.

1

There are 1 best solutions below

0
On

Just use StreamReader to read data line by line.

async void ReadPipe()
{
    using(var reader = new StreamReader(_currentServer))
    {
        while (true) 
        {
            var line = await reader.ReadLineAsync();
            if (line == null)
                break;

            //...
        }
    }
}

And on the server side, use StreamWriter.WriteLine to send data.

using(var writer = new StreamWriter(_currentServer))
{
    writer.WriteLine(...);
}