0

I'm learning C# and I've got a TCP server that works asynchronously and supports multiple connected clients that I'm having trouble keeping a consistent flow to a method processData(String) . I think I've managed to trace the issue down to the byte buffer where if I receive data from multiple clients (also if a single client sends the same data multiple times in quick succession).

I've tried using an isWorking bool to prevent processData() from being accessed and that threw a JSONReader Exception because I think the buffer was sending the incomplete string from processing. At this point I tried sending a EOF at the end of a string and having the processData() accessed when the check was true. However, this presented another problem where the buffer would contain half of one string and the beginning of another - at this point I posted on here thinking there may be a better approach to ensure properly formatted Strings were sent to the processData() method.

I also tried splitting the response into an array using the } as a pointer but this didn't work resulting in the same half of one string and the beginning of another issue.

  string data = content.Replace("[EOF]", "");
  string[] TooManyDataObjects = data.Split('}');
  string firstObject = TooManyDataObjects[0] += "}";

Here's the code I use to create a listen task and the handleDevice() method when a device connects.

 private async Task Listen()
        {
            try
            {
                while (true)
                {
                    Token.ThrowIfCancellationRequested();
                    TcpClient client = await server.AcceptTcpClientAsync();
                    client.NoDelay = true;
                    Console.WriteLine("Connected!");
                    await Task.Run(async () => await HandleDevice(client), Token);
                }
            }
            catch (SocketException e)
            {
                Console.WriteLine("Exception: {0}", e);
            }
        }

        private async Task HandleDevice(TcpClient client)
        {
            string data = null;
            Byte[] bytes = new Byte[8196];
            int i;

            try
            {
                using (stream = client.GetStream())
                {
                    while ((i = await stream.ReadAsync(bytes, 0, bytes.Length, Token)) != 0)
                    {
                        Token.ThrowIfCancellationRequested();
                        string hex = BitConverter.ToString(bytes);
                        data += Encoding.UTF8.GetString(bytes, 0, i);

                        //Console.WriteLine(data);
                        if (data.IndexOf("[EOF]") >= 0)
                        {
                            processData(data);
                            data = "";
                            Array.Clear(bytes, 0, bytes.Length);
                        }
                  
                    }
                }
            }
            catch (OperationCanceledException) { }
            catch (Exception e)
            {
                Console.WriteLine("Exception: {0}", e.ToString());
            }
            finally
            {
                client.Close();
            }
        }

Question: How can I get properly formatted string JSON responses received from clients to processData() in a queued or the received processing order?

2
  • Does this answer your question? C# exception thrown when parsing JSON String Commented Jul 31, 2022 at 1:34
  • This was asked and answered yesterday: You need to be aware of how your framing works: your framing is currently dumping the entire rest of the array, because stream.ReadAsync returns any amount of data. Commented Jul 31, 2022 at 1:35

1 Answer 1

0

I'm learning C# and I've got a TCP server that works asynchronously

Sorry, but you're trying to learn three fairly complex topics simultaneously? I strongly recommend you learn C#, sockets, and asynchrony one at a time. C# and asynchrony are fairly common, so I'd recommend learning those first; socket development is much more rare, so I'd learn that only if necessary.

the buffer would contain half of one string and the beginning of another

This is a common problem when starting out with socket programming. My first response to everyone running into this is to drop the sockets completely and use something much higher-level like ASP.NET Core (self-hosted if necessary).

But if you need sockets for some reason, then the proper solution for this socket problem (the first of several usually encountered) is message framing. I discuss message framing on my blog, as part of a series on socket programming in .NET. I also have a video series I did earlier this year on asynchronous socket programming that would be well worth watching if you really need to learn socket programming (again, the vast majority of developers never need to learn that).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.