Простой способ - использовать буфер, размер которого превышает максимальный размер сообщения, включая преамбулу. Поскольку вы сказали, что ни одно сообщение не будет больше 1400 байт, будет достаточно буфера 2048.
Псевдокод:
read a buffer
note no beginning of message
loop searching a preamble
search (memchr) the first character of the preamble (0x43 or `'C'`)
test is a full preamble is there - if not iterate previous search
Ok, we have a preamble
If a beginning of message was present
we have a full message : process it
If less that 1500 character remaining if the buffer
copy the content of the buffer starting with the current preamble to the beginning of the buffer
read enough bytes to have a full buffer
if EOF: FINISHED
Note the beginning of the message
end loop
Поскольку сообщения довольно короткие, я бы использовал буферизованное чтение (fread
) для использования стандартной буферизации библиотеки
Основа для реализации C:
const char preamble[] = {0x43, 0x78};
char buffer[2048];
size_t sz = fread(buffer, 1, sizeof(buffer), fd);
char *msg_start = NULL; // no start of message
char *search_start = buffer;
size_t search_size = sz;
for(;;) {
char *end = memchr(search_start, preamble[0], search_sz);
if (end == NULL) {
end = buffer + sz;
}
if ((end < buffer + sz - sizeof(preamble)) && memcmp(end, preamble, sizeof(preamble)) != 0) {
size_t delta = end - search_start + 1;
search_sz -= delta;
search_start += delta;
if (search_sz > sizeof(preamble)) continue;
end = buffer + sz;
}
if (msg_start != NULL) {
// process the message between msg_start and end
}
if (end == buffer + sz) break;
for (char *dest = buffer, char *src = end; src < end; src++, end++) *dest = *src;
size_t delta =fread(buffer + sz, 1, sizeof(buffer) + sz, fd);
if (delta == 0) break;
sz += delta
search_start = msg_start = buffer + sizeof(preamble);
}
ВНИМАНИЕ: не проверено и может содержать опечатки или неправильный код ...