1

I'm writing a java socket program to read data from server, I've no control to server, below is protocol agreed,

  • 2-bytes: magic number
  • 2-bytes: data length
  • N-bytes: ASCII string data payload
  • Big endian for the magic number and data length

For Example: if my request is "command/1/getuserlist" how to construct th request match above protocol and read the response back to List

I'm new to socket programming and have no idea how to build my request and read the response back.

can someone guide me how to build the request and read the response from

user207421
  • 305,947
  • 44
  • 307
  • 483
Sam
  • 6,215
  • 9
  • 71
  • 90

3 Answers3

1

According to the specification you must build a packet shaped in the following way

| 2 | 2 | N ........ |

Now this could be quite easy and there are multiple ways to do it, I suggest you one:

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

static byte[] buildPacket(int magicNumber, String payload) throws UnsupportedEncodingException
{
  // 4 bytes for header + payload
  ByteBuffer buffer = ByteBuffer.allocate(2 + 2 + payload.length());
  // we set that we want big endian numbers
  buffer.order(ByteOrder.BIG_ENDIAN);

  buffer.putShort((short)magicNumber);
  buffer.putShort((short)payload.length());
  buffer.put(payload.getBytes("US-ASCII"));
  return buffer.array();
}

public static void main (String[] args) throws java.lang.Exception
{
    try
    {
        byte[] bytes = buildPacket(0xFF10, "foobar");
        for (byte b : bytes)
          System.out.printf("0x%02X ", b);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

Mind that if you declare the method to accept a short magic number directly, you won't be able to pass a literal magic number > 32767 because short is signed in Java.

Jack
  • 131,802
  • 30
  • 241
  • 343
  • Check `ByteBuffer` documentation, there's everything you need: https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html – Jack Mar 12 '16 at 01:46
0

Use a DataOutputStream around a BufferedOutputStream around the `Socket.getOutputStream(). Then you can use:

  • writeShort() for the magic number
  • writeShort() for the length word
  • write() for the payload.

Similarly you can use DataInputStream and the corresponding readXXX() methods to read the response.

NB You are writing to a socket here, not a server socket.

user207421
  • 305,947
  • 44
  • 307
  • 483
-1

Watch out for the big endinanness!

DataxxxStream - although it is quite handy - does not offer a full support for both little and big endian numbers and arbitrary String encodings.

See my post at How to Read Byte Stream from Socket

Community
  • 1
  • 1
Gee Bee
  • 1,794
  • 15
  • 17
  • The question clearly specifies big-endian byte order. – user207421 Mar 13 '16 at 01:22
  • EJP, I respect your answers. I am wondering why do you ignore those edge cases where DataXxxxStream is *not* a solution, such as little endian data, and non utf8 string encoding in two separate questions?! – Gee Bee Mar 13 '16 at 21:05