0

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.

user10
  • 15
  • 4
  • Add a terminating character to send of transmission like EOT. then when you receive the EOT you know when to start processing. – jdweng Apr 04 '22 at 14:14
  • Is there any specific reason you want to use a Named Pipe? There are a bunch of different frameworks that allow you to pass *messages* between applications. These tend to be easier to use since they will deal with issues like this. – JonasH Apr 04 '22 at 14:15
  • Why is this method `async`? It doesn't use `await` anywhere. Do not confuse (or mix) task-based asynchrony with old-style asynchrony. The latter does not require (or work correctly with) `async`. – Jeroen Mostert Apr 04 '22 at 14:15
  • @ jdweng: because the string is read as a whole, I cannot pass an EOT ==> this would also be read multiple times. /r/n does not work ==> is there another method? – user10 Apr 04 '22 at 14:37
  • @ JonasH: I am grateful for any suggestion! – user10 Apr 04 '22 at 14:38
  • @ Jeroen Mostert: Thanks for the hint ==> but the method as void doesn't solve the problem either ... – user10 Apr 04 '22 at 14:40

1 Answers1

0

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(...);
}
shingo
  • 18,436
  • 5
  • 23
  • 42