Я пытаюсь написать программу клиент-сервер tcp для связи, ориентированной на сообщения.размер моего сообщения всегда составляет 1040 байт с включенным 16-байтовым заголовком.
Ниже приведен фрагмент кода.
class connection
{
....
#define BUFFER_SIZE 65535
uint8_t buffer[BUFFER_SIZE + BUFFER_SIZE];
std::size_t rem_buff = BUFFER_SIZE;
std::size_t avail_size = 0;
uint8_t *buffer_write = buffer;
uint8_t *buffer_reader = buffer;
Header mh;
long count = 0;
bool read_header = true;
};
void connection::read()
{
bool conn_terminated = false;
std::size_t read_bytes = 0;
if (rem_buff > 0) {
assert((buffer_write + rem_buff) <= (buffer + BUFFER_SIZE));
assert(buffer_write >= buffer_reader);
read_bytes = utils::read(handle(), buffer_write, rem_buff, conn_terminated, false);
if (read_bytes > 0) {
rem_buff -= read_bytes;
buffer_write += read_bytes;
avail_size = buffer_write - buffer_reader;
std::cout << "read_bytes : " << read_bytes
<< " avail_size : " << avail_size << ", rem_buff : " << rem_buff << std::endl;
} else if (conn_terminated) {
std::cout << "connection terminated" << std::endl;
return;
}
if (avail_size < 1) {
return;
}
}
do {
if (read_header) {
if (avail_size > sizeof(Header)) {
// header is ready
read_header = false;
mh = *(reinterpret_cast<Header*>(buffer_reader));
buffer_reader += sizeof(Header);
avail_size -= sizeof(Header);
std::cout << "payload : " << mh.length()
<< ", avail_size : " << avail_size
<< std::endl;
if (mh.length() > 1024) {
std::cout << "count : " << count << std::endl;
}
} else if (rem_buff == 0) {
// there is no space left to read complete header
memmove(buffer, buffer_reader, avail_size);
// reinit all pointers
buffer_reader = buffer;
buffer_write = buffer_reader + avail_size;
rem_buff = BUFFER_SIZE - avail_size;
std::cout << "move1: avail_size : " << avail_size << ", rem_buff : " << rem_buff << std::endl;
break;
} else {
// header is not complete
break;
}
}
if (!read_header) {
if (avail_size >= mh.length()) {
++count;
buffer_reader += mh.length();
avail_size -= mh.length();
read_header = true;
} else if (avail_size < mh.length()) {
// TODO: still not handling partial payload read
if (rem_buff == 0) {
// there is no space left to read complete header
memmove(buffer, buffer_reader, avail_size);
// reinit all pointers
buffer_reader = buffer;
buffer_write = buffer_reader + avail_size;
rem_buff = BUFFER_SIZE - avail_size;
std::cout << "move2: avail_size : " << avail_size << ", rem_buff : " << rem_buff << std::endl;
}
break;
}
}
} while (avail_size > 0);
}
случайным образом, то есть иногда после 1000 сообщений или иногда 30000 сообщений внезапно я получаю очень большую длину полезной нагрузки, и чтение полностью прекращается.
payload : 1024, avail_size : 1039
move1: avail_size : 15, rem_buff : 65520
read_bytes : 6225 avail_size : 6240, rem_buff : 59295
payload : 45680032226158504, avail_size : 6224