Я изучаю c ++ для того, чтобы создать небольшое приложение, которое отображает поток изображений. Изображения поступают с устройства j2me, которые не сохраняются в виде файла (поэтому у меня есть только байты).
Я думаю, мне нужно сначала отправить размер изображения в виде целого числа, чтобы клиент знал, сколько нужно прочитать для этого конкретного изображения в потоке.
Моя проблема в том, что размер всегда слишком велик, а не размер изображения, когда я сначала просто пытаюсь прочитать размер (я отправляю эту длину на java-сервер в socket.write (int) и пробовал dataoutputstream.writeInt). Я опубликую некоторый код, поскольку он, вероятно, довольно прост.
Почему размер отличается от того, что я отправляю?
ssize_t
readLine(int fd, char *buffer, size_t n)
{
ssize_t numRead, tt; /* # of bytes fetched by last read() */
size_t totRead; /* Total bytes read so far */
char *buf;
char ch;
if (n <= 0 || buffer == NULL) {
return -1;
}
buf = buffer; /* No pointer arithmetic on "void *" */
totRead = 0;
for (;;) {
numRead = read(fd, &ch, 1);
tt += numRead;
if (numRead == -1) {
return -1; /* Some other error */
} else if (numRead == 0) { /* EOF */
if (totRead == 0) /* No bytes read; return 0 */
return 0;
else /* Some bytes read; add '\0' */
break;
} else { /* 'numRead' must be 1 if we get here */
if (totRead < n - 1) { /* Discard > (n - 1) bytes */
totRead++;
*buf++ = ch;
}
if (ch == '\n')
break;
}
}
printf("read line %s ", buf);
fflush(stdout);
int test = (int)buf;
printf("read line int %i ", tt);
fflush(stdout);
*buf = '\0';
return totRead;
}
WBXML
определяет независимый от платформы способ записи int
ценности: Многобайтовые целые числа.
Многобайтовое целое число состоит из серии октетов, где самый значимый бит — это флаг продолжения, а оставшиеся семь битов — это скалярное значение. Флаг продолжения указывает, что октет не является концом многобайтовой последовательности. Одно целочисленное значение кодируется в последовательность из N октетов. Первые N-1 октеты имеют флаг продолжения, установленный в значение один (1). Последний октет в серии имеет значение флага продолжения ноль (0).
Оставшиеся семь битов в каждом октете кодируются в порядке с прямым порядком байтов, например, самый старший бит в первую очередь. Октеты расположены в порядке с прямым порядком байтов, например, старшие семь битов передаются первыми. В ситуации, когда начальный октет имеет значение менее семи бит, все неиспользуемые биты должны быть установлены в ноль (0).
Например, целочисленное значение 0xA0 будет закодировано двухбайтовой последовательностью 0x81 0x20. Целочисленное значение 0x60 будет закодировано однобайтовой последовательностью 0x60.
Я сделал это для Java ME и Bada, но это довольно просто реализовать на любом языке.
Ваш код чтения обрабатывает текстовые файлы, он работает один символ за другим, он проверяет наличие новых строк и т. Д.
Изображение («так у меня просто есть байты»), похоже, двоичные данные. Когда вы интерпретируете двоичные данные как текст, вы получаете всевозможные случайные ошибки. Эти двоичные данные могут включать в себя, например, «\ n», когда значение пикселя равно 13. Они также могут включать в себя «\ 0», который завершит строку перед фактическим концом.
Когда вы сначала сохраняете размер, вы отправляете его как int, которое представляет собой 4 байта. Когда вы читаете его как 4 отдельных символа, вы получаете мусор.
Вам также необходимо остерегаться порядка / байтов байтов. Java использует «сетевой порядок», на x86 C может читать его наоборот.
Вы используете старую стандартную C lib. Может быть проще использовать C ++ iostreams.