Search code examples
c#network-programmingtcpclientnetworkstream

Network stream seems to stop reading?


I have a program which uses a TCPClient and network stream to read in data from a ip and port. Messages are constantly being sent to the program at a fast pace. The program is designed to read in these messages, and translate the messages so they display the information sent to a more readable format for the user.

This seems to be working fine - for around 60 seconds. For some reason it then seems to stop reading in messages. No error messages are displayed, just no new messages come through. When I stop and start the program it works fine again, until a minute or so has passed.

Below is the code I have used. Hopefully you'll be able to see where I may have gone wrong which could cause the stream to stop getting new messages. In the main:

public MainWindow()
{
    InitializeComponent();

    client.Connect(address, port); //client, address and port are declared as public and static

    connected = true;

    if (connected == true)
    {
        readInTxtBox.Text = "Connected";
    }


    Thread t = new Thread(ReadInandOutputToTextBoxIfInvoke);
    t.IsBackground = true;
    t.Start(); //the thread is where the messages are read in
}

And this is the method:

private void ReadInandOutputToTextBoxIfInvoke()
{
    while (true)
    {
        string message = "";
        int x = 0;
        int start = 35;
        int messageLength;
        int numberOfMessages;
        NetworkStream nwStream = client.GetStream();
        try
        {
            while ((x = nwStream.ReadByte()) != start) { if (x == -1) { continue; } } //if it doesnt begin with # or has gone over then break

            //reads in message header which is length then number of messages
            messageLength = nwStream.ReadByte();
            numberOfMessages = nwStream.ReadByte();

            string messageRecieved = new string(readMessage(nwStream, messageLength - 1));
            string[] messages = messageRecieved.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);


            for (int i = 0; i < numberOfMessages; i++)
            {
                string messageToProcess = messages[i];
                char messageType = messageToProcess[0];
                switch (messageType)
                {
                    case 'h':
                        try
                        {
                            heightMsg.Translate(Utilities.ConvertHexStringToByteArray(messageToProcess.Substring(1)));
                        }
                        catch { }
                        break;
                    case 'l':
                        try
                        {
                            longWarpHeightMsg.Translate(Utilities.ConvertHexStringToByteArray(messageToProcess.Substring(1)));
                        }
                        catch { }
                        break;
                    case 's':
                        try
                        {
                            status.Translate(Utilities.ConvertHexStringToByteArray(messageToProcess.Substring(1)));
                        }
                        catch { }
                        break;
                    case 'r':
                        try
                        {
                            calibrateMsg.Translate(Utilities.ConvertHexStringToByteArray(messageToProcess.Substring(1)));
                        }
                        catch { }
                        break;
                    default:
                        break;
                }
            }

The case statement just translate the message so may not be relevent.

Update - I have added a console.writeline to my catch statements to output any errors and no errors seem to occur. Please see below the edit I have made:

switch (messageType)
{
    case 'h':
        try
        {
            heightMsg.Translate(Utilities.ConvertHexStringToByteArray(messageToProcess.Substring(1)));
        }
        catch (Exception e)
        { Console.WriteLine(e.ToString()); }
        break;
    case 'l':
        try
        {
            longWarpHeightMsg.Translate(Utilities.ConvertHexStringToByteArray(messageToProcess.Substring(1)));
        }
        catch(Exception e) { Console.WriteLine(e.ToString());  }
        break;
    case 's':
        try
        {
            status.Translate(Utilities.ConvertHexStringToByteArray(messageToProcess.Substring(1)));
        }
        catch(Exception e) { Console.WriteLine(e.ToString());  }
        break;
    case 'r':
        try
        {
            calibrateMsg.Translate(Utilities.ConvertHexStringToByteArray(messageToProcess.Substring(1)));
        }
        catch(Exception e) { Console.WriteLine(e.ToString());  }
        break;
    default:
        break;
}

Solution

  • The problem turned out to be the device I was speaking to had to receive a keep alive message within a certain amount of time, otherwise it closed the connection. It now works - I send it a keep alive message every 8 seconds.