LINUX.ORG.RU

c++ передача данных по сети


0

0

Всем привет. Есть класс, содержащий десяток double-переменных. Необходимо передать эти данные(по сути, нужна сериализация/десериализация данных) по сети. Не хотелось бы использовать ничего стороннего, помимо glib & bsd-sockets. В голову не приходит ничего умнее текстовой передачи данных и парсинг(текста) на стороне сервера(с превращением обратно в double), но это пожалуй, самы не эффективный способ. Подскажите пожалуйста, в какую сторону копать и что можно почитать. Задача банальна. Есть ли возможность(буду благодарен за ссылки на документы или код) передавать бинарные данные или как-то еще?!

anonymous

glib? C++? O_O

Это всё типа шутка?

tailgunner ★★★★★
()

>> самы не эффективный способ

самый неэффективный способ это наверно XML. Зато энтерпрайзно.

А так лучше всего просто текстом, если конечно ты не собираешься гонять гигабайты данных/объектов по сети.

alex_custov ★★★★★
()

Если double хранится по стандарту IEEE, то достаточно байты преобразовать в network byteorder (big endian) и отправить в сеть, на принимающей стороне преобразовать в host byteorder.

Reset ★★★★★
()
Ответ на: комментарий от Reset

2Reset, спасибо, именно это мне и нужно. Не подскажешь, где об этом можно почитать подробнее(скорее не про преобразование big endian/little endian, а про саму передачу и восстановление)?

anonymous
()
Ответ на: комментарий от anonymous

Получил я recv'ом данные на сервере, что с ними сделать, дабы получить double? 

double x;
memcpy(x, received_buff, sizeof(double));

Так что ли?

anonymous
()
Ответ на: комментарий от alex_custov

а что мешает побайтно передать(кроме кроссплатформенности :))? Типа так(не запускал и не отлаживал :)):

double var=123456789;
void *ptr = &car;

for (int x=0; x<sizeof(var); x++, ptr++) {
    write(fd, ptr, 1);
}

Как распаковывать придумай сам :). Кстати, я бы буфер для передачи сделал чтобы передать всё одним махом а не плодить системные вызовы.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

а зачем передавать double в бинарном виде? ради экономии считанных байт? можно же в scientific нотации через sprintf строки получить.

dilmah ★★★★★
()

Это конечно нарушает требование "не использовать ничего стороннего", но мне кажется наиболее удачным вариантом: http://code.google.com/p/protobuf/ позволяет сериализовать данные в бинарный вид для удаленного вызова методов.

svyatogor ★★★★★
()
Ответ на: комментарий от dilmah

>а зачем передавать double в бинарном виде? ради экономии считанных байт?

Ради предсказуемости протокола (в двоичном виде всегда передается 8 байт, в текстовом - поле переменной длины, 12 символов легко - это 50% оверхэда вообще на ровном месте) и уменьшения времени на преобразование (переставить местами байты гораздо быстрее, чем вызвать sprintf/sscanf).

tailgunner ★★★★★
()
Ответ на: комментарий от Reset

на отправляющей стороне:

double value;
uint64_t w;
vector < uchar > data;

memcpy(&w, &value, 8);

data.push_back(w >> 56);
data.push_back(w >> 48);
data.push_back(w >> 40);
data.push_back(w >> 32);
data.push_back(w >> 24);
data.push_back(w >> 16);
data.push_back(w >> 8);
data.push_back(w);

посылаем data в сеть

на принимающей стороне:
uchar * data; //принятые данные
double value;
uint64_t w = 0;
w |= (uint64_t)*data++ << 56;
w |= (uint64_t)*data++ << 48;
w |= (uint64_t)*data++ << 40;
w |= (uint64_t)*data++ << 32;
w |= (uint64_t)*data++ << 24;
w |= (uint64_t)*data++ << 16;
w |= (uint64_t)*data++ << 8;
w |= (uint64_t)*data++;
memcpy(&value, &w, 8);

на платформах с хранением double по стандарту IEEE всё будет работать независимо от endianess

Reset ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.