Joaquin
Joaquin

Reputation: 21

How to make sure I wont lose data from TCP?

I'm sorry if I'm asking something asked before.

I'm developing a program that reads data received via TCP and using a StreamReader, and I just can't find how to make sure that any data won't be missed. Is there any way to create a middle buffer to read from there or something like that?

Here are the methods I've created for receiving data and write it to a text box:

public static void Connect(string IP, string port)        
{
    try
    {
        client = new TcpClient();
        IPEndPoint IP_End = new IPEndPoint(IPAddress.Parse(IP), int.Parse(port));
        client.Connect(IP_End);
        if (client.Connected)
        {
            connected = "Connected to Exemys!" + "\r\n";
            STR = new StreamReader(client.GetStream());
            bgWorker = true;
        }
    }
    catch (Exception x)
    {
        MessageBox.Show(x.Message.ToString());
    }
}

-

public static void MessageReceiving(TextBox textBox)
{
    try
    {
        string values =Conection.STR.ReadLine();
        textBox.Invoke(new MethodInvoker(delegate () { textBox.AppendText("Exemys : " + values.Substring(2) + Environment.NewLine); }));
        try
        {
            string messagetype = values.Substring(5, 1);
            string ID = values.Substring(3, 2);
            string checksum = values.Substring(values.Length - 2, 2);
            if (checksum == CalcularChecksum(values.Substring(3, values.Length - 5)))
            {
                if (messagetype == "N")
                {
                    if (ID == "01")
                    {
                        ID1 = values.Substring(3, 2);
                        messagetype1 = values.Substring(5, 1);
                        capacity1 = values.Substring(6, 1);
                        pressure1 = values.Split(',')[1];
                        sequencetime1 = values.Split(',')[2];
                        runstatus1 = values.Split(',')[3];
                        mode1 = values.Split(',')[4].Substring(0, 1);
                        checksum1 = CalcularChecksum(values.Substring(3, values.Length - 5));
                    }
                    if (ID == "02")
                    {
                        ID2 = values.Substring(3, 2);
                        messagetype2 = values.Substring(5, 1);
                        capacity2 = values.Substring(6, 1);
                        pressure2 = values.Split(',')[1];
                        sequencetime2 = values.Split(',')[2];
                        runstatus2 = values.Split(',')[3];
                        mode2 = values.Split(',')[4].Substring(0, 1);
                        checksum2 = CalcularChecksum(values.Substring(3, values.Length - 5));
                    }
                }
            }

        }
        catch(Exception x)
        {
            MessageBox.Show(x.Message.ToString());
        }
    }
    catch (Exception)
    {
        MessageBox.Show("Client disconnected.");
    }
}

Edit: what I'm trying to ask is how to always process the entire data before continue receiving? That would be the question.

Upvotes: 1

Views: 62

Answers (2)

Joaquin
Joaquin

Reputation: 21

Thanks for the response, but after searching, I've found what I was looking for. I wanted to store those messages (data) that were entering to make sure that I won't lose them (for any reason, more precisely that the receiving process would be faster than the message processing operation), so I used Queue to achieve this.

 public static void RecepcionMensajes(TextBox textBox)
    {
        if (client.Connected == true)
        {
            try
            {
                string fifo = Conexion.STR.ReadLine();
                Queue mensajes = new Queue();
                //Aquí se ponen en cola los mensajes que van llegando, utilizando el sistema FIFO.
                mensajes.Enqueue(fifo);
                string values = mensajes.Dequeue().ToString();
                textBox.Invoke(new MethodInvoker(delegate () { textBox.AppendText("Exemys : " + values.Substring(2) + Environment.NewLine); })); 

Upvotes: 0

Ewald Benes
Ewald Benes

Reputation: 632

A TCP stream is a stream of bytes that ends when the socket is closed by you or the remote peer or breaks because of network issues. In order to get everything from the stream you need to call the StreamReader.ReadLine method inside a loop into a buffer until some stop condition applies.

...
try
{
    while(true)
    {
        ...
        input = STR.ReadLine();
        if (input == <some stop condition>)
            break;
        ...
    }
}
...

That's a highly simplified example. TCP reading with partial buffer handling can be a complex beast so I recommend to use a library or framework if you're doing more than some hobby project.

Upvotes: 1

Related Questions