Как анализировать данные в C ++ - PullRequest
0 голосов
/ 17 июня 2011
  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);

Я отправляю байтовые данные вот так и хочу проанализировать их на своем linux-сервере с помощью c ++

В c ++ я читаю

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

и нажимаю pdataв очередь pthread.Я думаю, что мне нужно прочитать первый байт, чтобы увидеть тип пакета, и прочитать следующие 8 байт, чтобы получить идентификатор устройства и т. Д. Пожалуйста, дайте мне несколько ссылок или учебник, чтобы сделать это в коде c ++ ..

Заранее спасибо ..

Ответы [ 3 ]

1 голос
/ 17 июня 2011

Приведенный ниже код эффективно справится с задачей. Я предполагаю, что Java int является 32-битным

#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';

Примечание: я приукрашиваю некоторые вещи, а именно

  • Не обрабатывается, когда BUF_SIZE имеет малое значение
  • Не обрабатывает, когда машина на языке C не является немного ENDIAN. Если это порядковый номер с большим порядком байтов, вам нужно переключить байты после memcpy для device_id и name_len
  • Не печатать приведение к вызовам memcpy, чтобы избежать возможных предупреждений компилятора

Это решение на чистом C, также будет работать на C ++

0 голосов
/ 17 июня 2011

Использование библиотеки IOStream - это почти то же самое, что вы могли бы сделать, используя обычное чтение и запись без промежуточного буфера в C. т.е.

#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';
}

Еще раз, я не проверяю ошибки на istream:: чтение вызовов, беспокойство по поводу порядка байтов или вставка приведений типа.Попытка сделать это простым.

0 голосов
/ 17 июня 2011

Если у вас есть контроль над кодом Java, и вам не нужно реализовывать стандартный сетевой протокол, я бы порекомендовал другой подход. Вместо того, чтобы перемещать байты на этом низком уровне, вы можете использовать библиотеку сериализации более высокого уровня, например Буферы протокола Google . Существуют учебники по C ++ и учебники по Java , с которых следует начать.

...