Lucy Copp
Lucy Copp

Reputation: 95

Unable to write and read to a network stream at the same time c#

I have a program which uses a TCPClient and Network Stream to recieve messages from an external IP. Messages are constantly being sent and the program translates these messages into a more readable format for the user.

However, the IP needs to recieve a keep alive message every 8 seconds to keep the connection open.

I seem to be having difficulty reading in messages, and writing to the stream at the same time. I was under the impression you could read and write to a stream as long as they were on different threads.

Once the timer has elapsed, and the method to write the keep alive message is called, I get the error: Unable to read data from the transport connection: An established connection was aborted by the software in your host machine. This error occurs when it is trying to read in a byte after the write to stream method has been called.

Below is my code. This is the main:

public MainWindow()
    {
        InitializeComponent();

        client.Connect(address, port);
        nwStream = client.GetStream();

        System.Timers.Timer newTimer = new System.Timers.Timer(8000);
        newTimer.Elapsed += delegate { KeepAlive(nwStream, newTimer); };
        newTimer.Start();
        Thread t = new Thread(ReadInandOutputToTextBoxIfInvoke);
        t.Start();
    }

Here is the thread and method which reads from the stream:

 private void ReadInandOutputToTextBoxIfInvoke()
    {

        while (run)
        {
            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];

I removed a chunk of that method which translates the message as it isn't relevent.

This is the code which is called when the timer has elapsed:

    private void KeepAlive(NetworkStream Ns, System.Timers.Timer MyTimer)
    {
        byte[] toSend = new byte[] { 35, 51, 49, 42, 124 };
        try
        {
            for (int i = 0; i < toSend.Length; i++)
            {
                Ns.WriteByte(toSend[i]);
                Ns.Flush();
            }
        }
        catch
        {
            MyTimer.Close();
        }
    }

Upvotes: 1

Views: 556

Answers (1)

Lucy Copp
Lucy Copp

Reputation: 95

I have now solved my issue. There were two factors preventing the program from working properly.

  1. The error stopped appearing after I had used a lock.
  2. The message I was sending to the device was not in the correct format - it had to be in hex

It now works perfectly. Thank you to everyone who tried to help.

Upvotes: 1

Related Questions