• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2080
  • Last Modified:

C# Socket Server - read all data until socket is closed.

Hi,

I'm writing a socket server in c#.

The client sends me multiple records in each connection with a slight pause between each record. When the client is finished sending data it disconnects itself. There is no end of data signal (eg: <EOF>) .

As a result of the pause between records, "readStream.DataAvailable" is returning 'false' when, in fact, there is more data to be read.

I have temporarily fixed the code by adding a sleep timer.

How do I continue reading data, until the connection is closed? (rather then use 'readStream.DataAvailable')

        public mtsWorker(System.Net.Sockets.TcpClient client)
        {
            try
            {
                // buffer to read data from socket partially
                byte[] buffer = new byte[client.ReceiveBufferSize]; 
                NetworkStream readStream = client.GetStream();

                if (readStream.CanRead)
                {
                    StringBuilder completeMessage = new StringBuilder();

                    int numberOfBytesRead = 0;

                    // Incoming message may be larger than the buffer size.
                    do
                    {
                        numberOfBytesRead = readStream.Read(buffer, 0, buffer.Length);

                        completeMessage.AppendFormat("{0}", Encoding.ASCII.GetString(buffer, 0, numberOfBytesRead));
                        System.Threading.Thread.Sleep(500);
                    }
                    while (readStream.DataAvailable);
                    
                }

                // close connection
                client.Close();
            }
            catch(Exception ex)
            {
                Console.WriteLine("Error during connection handling occured: " + ex.Message);
            }
        }

Open in new window


Thankyou
0
mhdi
Asked:
mhdi
1 Solution
 
käµfm³d 👽Commented:
I haven't tested this, but I believe Read will block whilst waiting for data, so you should be able to incorporate that into the loop:

public mtsWorker(System.Net.Sockets.TcpClient client)
{
    try
    {
        // buffer to read data from socket partially
        byte[] buffer = new byte[client.ReceiveBufferSize]; 
        NetworkStream readStream = client.GetStream();

        if (readStream.CanRead)
        {
            StringBuilder completeMessage = new StringBuilder();

            int numberOfBytesRead = 0;

            // Incoming message may be larger than the buffer size.
            while ((numberOfBytesRead = readStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                completeMessage.AppendFormat("{0}", Encoding.ASCII.GetString(buffer, 0, numberOfBytesRead));
                System.Threading.Thread.Sleep(500);
            }
        }

        // close connection
        client.Close();
    }
    catch(Exception ex)
    {
        Console.WriteLine("Error during connection handling occured: " + ex.Message);
    }
}

Open in new window

0
 
mhdiAuthor Commented:
Thanks for that. But it didn't seem to resolve the issue.

I found that the client sends \r\n\r\n at the end of each transmission.

So I'm now using this bit of code which I think is working. Do you see any reasons why it wouldn't?

if (readStream.CanRead)
    {
        StringBuilder completeMessage = new StringBuilder();

        const int connectionTimeout = 5000; // set up 5 second timeout
        int numberOfBytesRead = 0;

        bool connectionExceed = false;
        Stopwatch start = Stopwatch.StartNew();

        // Incoming message may be larger than the buffer size.
        do
        {
            numberOfBytesRead = readStream.Read(buffer, 0, buffer.Length);

            string stringRepresentation = Encoding.ASCII.GetString(buffer, 0, numberOfBytesRead);
            completeMessage.AppendFormat("{0}", stringRepresentation);

            if (stringRepresentation.Contains("\r\n\r\n"))
                connectionExceed = true;

            mts_file.Log(String.Format("Thread with ID={0} read data chunk with length {1}, and data = {2}", thread_id, numberOfBytesRead, completeMessage));


        }
        while (!connectionExceed && (start.ElapsedMilliseconds < connectionTimeout) /*readStream.DataAvailable*/);

        mts_file.Log(String.Format("Thread with ID={0} all data read", thread_id));

        // handle data
        HandleData(completeMessage.ToString());
    }

Open in new window

0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now