Juan
Juan

Reputation: 13

How to read Big Endian strings

I am very unexperted in this field, I need to recieve a string from a server which it`s not mine, here is the protocol:

All messages to Scratch must be sent to port 42001 in this format:

After the zero bytes is the length of the string message to pass, given as a 32-bit big-Endian number (4 bytes). Lastly, there is the string message, whose length is the length of the message size. Like this:

[size][size][size][size][string message (size bytes long)]

My program is able to connect and recieve a data, but I can't convert it to string.

public class SynchronousSocketClient {

public static void StartClient(IPAddress IP) {
    // Data buffer for incoming data.
    byte[] bytes = new byte[1024];

    // Connect to a remote device.
    try {
        // Establish the remote endpoint for the socket.

        IPEndPoint remoteEP = new IPEndPoint(IP, 42001);

        // Create a TCP/IP  socket.
        Socket sender = new Socket(AddressFamily.InterNetwork, 
            SocketType.Stream, ProtocolType.Tcp );

        // Connect the socket to the remote endpoint. Catch any errors.
        try {
            sender.Connect(remoteEP);

            Console.WriteLine("Socket connected to {0}",
                sender.RemoteEndPoint.ToString());

            // Receive the response from the remote device.
            int bytesRec = sender.Receive(bytes);
            Console.WriteLine("Bytes Recibidos : {0}", bytesRec);

            //HERE IS THE PROBLEM...

            Console.WriteLine("Echoed test = "+
                System.Text.Encoding.BigEndianUnicode.GetString(bytes, 0, bytesRec));

           /* // Encode the data string into a byte array.
            byte[] msg = Encoding.ASCII.GetBytes("broadcast \"YES\"");

            // Send the data through the socket.
            int bytesSent = sender.Send(msg);*/



            // Release the socket.
            sender.Shutdown(SocketShutdown.Both);
            sender.Close();

        } catch (ArgumentNullException ane) {
            Console.WriteLine("ArgumentNullException : {0}",ane.ToString());
        } catch (SocketException se) {
            Console.WriteLine("SocketException : {0}",se.ToString());
        } catch (Exception e) {
            Console.WriteLine("Unexpected exception : {0}", e.ToString());
        }

    } catch (Exception e) {
        Console.WriteLine( e.ToString());
    }
}}

Upvotes: 1

Views: 1383

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062512

First, read the length:

byte[] buffer = ...
ReadExactly(stream, buffer, 0, 4);

void ReadExactly(Stream stream, byte[] data, int offset, int count)
{
    int read;
    while(count > 0 && (read = stream.Read(data, offset, count)) > 0)
    {
        offset += read;
        count -= read;
    }
    if(count != 0) throw new EndOfStreamException();
}

Now parse that big-endian sytle:

int len = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];

Now read the payload; for example:

ReadExactly(stream, buffer, 0, len);

And get the string, for which you need to know the encoding; I'm assuming UTF-8 here:

string s = Encoding.UTF8.GetString(buffer, 0, len);

Upvotes: 2

Related Questions