3
\$\begingroup\$

I am developing some software that uses a pretty ancient low-level TCP/IP protocol from (I think) the eighties. I can send messages to the server very reliably, but I am a little unsure about receiving them. I cannot predict when the server will send me a message, so I have this method in an infinite loop. GetNextMessage() blocks the thread until it receives a message, whereupon the message is acted upon, and the loop repeats.

Messages are sent at a rate of about maybe 5 or 6 a minute, and I can process them in less than a quarter of a second, so I'm not currently spinning off a new thread when I receive them.

This code fragment contains all the relevant symbols and the logic that I am unsure of:

    /// this is filled earlier in the program
    private Socket _socket;

    private const int BufferSize = 4096;

    /// <summary>
    /// This byte (hex 02) indicates the start of the message.
    /// </summary>
    private const byte RecordStart = 2;

    /// <summary>
    /// This byte (hex 03) indicates the end of the message.
    /// </summary>
    private const byte RecordEnd = 3;

    private string GetNextMessage()
    {
        byte[] bytesReceived = new byte[BufferSize];

        // ReSharper disable PossibleNullReferenceException
        _socket.Receive(bytesReceived);
        // ReSharper restore PossibleNullReferenceException

        if (_socket.Poll(1, SelectMode.SelectRead))
        {
            throw new SocketException((int)SocketError.ConnectionReset);
        }

        IEnumerable<byte> bytes = bytesReceived
            .Where(character => character != RecordStart)
            .TakeWhile(character => character != RecordEnd);

        return Encoding.ASCII.GetString(bytes.ToArray());
    }

My concerns:

  1. I am not sure if _socket.Poll() is the correct way to determine if the socket has gone away. It most certainly works and is very necessary, but I'm sure I should be doing something else.
  2. I once performed an operation that sent three messages immediately after each other, but I only appeared to receive two of them. It is possible that there is a bug in the product I am developing for (seems likely), but I am worried that the method I have chosen is somehow causing messages to be discarded.
\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

One thing I do with reading from sockets is separate receiving of the data from what the data contains.

Meaning, you may get your information in progressive chunks..... so receive a chunk of data, then see if you have a complete "Message". If not, wait for the next chunk of data. When you have your full "Message" then you can pass that on to whatever wants it.

In fact what I have done is abstract the idea of a streaming connection so I can interchange serial ports / tcp sockets / and any other streaming type connection. Have something that receives from a connection, and then do interpreting.

\$\endgroup\$
1
\$\begingroup\$

A: 1. Here's a better way to check if a socket has disconnected.

    bool SocketConnected(Socket s)
    {
        bool part1 = s.Poll(1000, SelectMode.SelectRead);
        bool part2 = (s.Available == 0);
        if (part1 & part2)
            return false;
        else
            return true;
    }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.