0
  final byte LOGIN_REQUEST = 1;
  long deviceId = 123456789;
  String nickname = "testid";

  Socket mSocket = new Socket("localhost", 12021);
  ByteBuffer bBuffer = ByteBuffer.allocate(1);
  bBuffer.order(ByteOrder.LITTLE_ENDIAN);

  //1
  bBuffer.put(LOGIN_REQUEST);

  //8
  bBuffer.putLong(deviceId);

  byte[] bString = nickname.getBytes();
  int sLength = bString.length;

  //4
  bBuffer.putInt(sLength);
  bBuffer.put(bString);

I am sending byte data like this and I want to parse it on my linux server using c++

In c++, I am reading

 char *pdata = new char[BUF_SIZE];
 int dataLength = read(m_events[i].data.fd, pdata, BUF_SIZE);

and push the pdata into the pthread's queue. I think I have to read first byte to see the type of the packet and read the next 8byte to get the device id and so on.. Please give me some references or tutorial to do this in c++ code..

Thanks in advance..

3 Answers 3

1

The below code will effectively do the trick. I am assuming a java int is 32bit

#include <inttypes.h>

// Declare variables
unsigned char login_req;
int64_t       device_id;
uint32_t      name_len;
char*         name_str;

// Populate variables;
login_req = pdata[0];
memcpy( &device_id, pdata+1, 8 );
memcpy( &name_len, pdata+9, 4 );
name_str = (char*)malloc( name_len + 1 );
memcpy( name_str, pdata+13, name_len );
name_str[name_len] = '\0';

Note: I am glossing over some stuff, namely

  • Does not handle when BUF_SIZE is to small
  • Does not handle when the C program machine is not little ENDIAN. If it is big endian then you would need to switch the bytes after the memcpy for device_id and name_len
  • Does not to type cast on memcpy calls to avoid possible compiler warnings

This solution is pure C, will work in C++ too

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your answer. I look up online and I found a code using fstream and iostream. Is this same using this and using memcpy? Could you please provide any tutorials or examples using these fstream and iostream ? Thanks in advance..
0

If you have control over the Java code, and there's not a standard network protocol you have to implement, then I would recommend a different approach. Instead of pushing bytes around at this low a level, you can use a higher level serialization library, such as Google Protocol Buffers. There are both C++ tutorials and Java tutorials, which should get you started.

Comments

0

Using the IOStream library is pretty much the same as you could have done using basic read and write without the intermediate buffer in C. i.e.

#include <inttypes.h>
#include <iostream>

void readData( std::istream input )
{
    // Declare variables
    unsigned char login_req;
    int64_t       device_id;
    uint32_t      name_len;
    char*         name_str;

    // Populate variables;
    input.read( &login_req, 1 );
    input.read( &device_id, 8 );
    input.read( &name_len, 4 );
    name_str = (char*)malloc( name_len + 1 );
    input.read( name_str, name_len );
    name_str[name_len] = '\0';
}

Once again I am not error checking on the istream::read calls, worrying about endian issues, or putting in the type casts. Trying to keep it simple.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.