1

Hi I'm a bit new to this, short story is I have a device which act as TCP server, I tested the device with Hercules Tool and it works as expected, the problem is in my code:

using System;
using System.IO;
using System.Net.Sockets;
using System.Text;

namespace ModbusJsonTest
{
    class Program
    {
        static void Main(string[] args)
        {
            const int PORT_NO = 30001;
            const string SERVER_IP = "192.168.1.1";
            TcpClient client = new TcpClient(SERVER_IP, PORT_NO);
            StreamReader sr = new StreamReader(client.GetStream());
            StreamWriter sw = new StreamWriter((client.GetStream()));

        StringBuilder request = new();
        request.Append("{");
        request.Append("\"funcCode\":3,");
        request.Append("\"slaveId\":31,");
        request.Append("\"address\":0,");
        request.Append("\"quantity\":2,");
        request.Append("\"interval\":0");
        request.Append("}");

        Console.WriteLine(request.ToString());

        sw.WriteLine(request.ToString());
        sw.Flush();

        string data = sr.ReadLine();
        while(data!=null)
        {
            Console.WriteLine(data);
            data = sr.ReadLine();
        }
        client.Close();
    }
}

}

This above code sends the following request:

{"funcCode":3,"slaveId":31,"address":0,"quantity":2,"interval":0}

Expecting to get the following respone:

[{"slaveId":31,"funcCode":3,"address":0,"quantity":2,"data":[4,0,0,0,235]}]

As you can see it works when using Hercules:

enter image description here

I checked if my code is able to send the request to the device correctly, seems like it works, I catched this message using Hercules as server (insted the device being the server)

enter image description here

I can't figure out what am I doing wrong, are there any useful code examples I can try ?

EDITED: the code is stuck on string data = sr.ReadLine(); the code does not continue to execute pass this...

  • Have you tried sending your expected reply using Hercules? – PaulF Sep 06 '21 at 13:43
  • 1
    Could be that your sever is not responding with an end of line character as described within the remarks of https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader.readline?view=net-5.0. Specifically, there is no `\r`, `\n`, or `\r\n` at the end of your expected response so `sr.ReadLine()` neither reaches a line end or the end of stream. – George Kerwood Sep 06 '21 at 13:44
  • Also, try using Read rather than ReadLine – PaulF Sep 06 '21 at 13:45

2 Answers2

0

Your issue is that sr.ReadToEnd() will never complete because the stream isn't ended (and, it won't ever end - it's a continuous stream between the server and the client).

Instead, you need to read in the reply either with a buffer, or by assuming the response is terminated with a new-line and reading a line at a time.

For example, the following code will read in a single line of text if it is terminated with a new-line.

sw.WriteLine(request.ToString());
sw.Flush();

// Read in a single line of the reply.
string line;
while(!string.IsNullOrEmpty(line = sr.ReadLine())) 
{
    Console.WriteLine(line);
}

You can also read in a byte-array using one of the overloads of Stream.Read.

RB.
  • 36,301
  • 12
  • 91
  • 131
  • Hi, this does not work, I put a breakpoint on "line.Dump();" but the code never reaches it, the code is stuckk on "line = sr.ReadLine()" , what coud this mean ? – Tom Boudniatski Sep 06 '21 at 13:36
  • 1
    It means your TCP server is not terminating the response with a new-line. You will need to use one of the byte-overloads and read in the string manually. Apologies for leaving `line.Dump()` in - that's a Linqpad extension, and won't compile.... I'll fix it. I'm just working on a byte sample for you as well. – RB. Sep 06 '21 at 13:53
0

I was able to find this post here:

Server Client send/receive simple text

The code discribed there solved the issue, I guess StreamReader is not the correct tool for this kind of work...