TCP-сервер: Recv() с динамически увеличивающимся размером буфера.C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 TCP-сервер: Recv() с динамически увеличивающимся размером буфера.

Сообщение Anonymous »

Я пытаюсь прочитать все данные, отправленные клиентом на TCP-сервер, не зная заранее, насколько большими могут быть данные, и не ограничивая размер получаемого буфера. TCP-сервер основан на epoll(), а сокеты неблокируются. Сервер является многопоточным: основной цикл событий проверяет, является ли событие epoll новым соединением, то есть дескриптором файла сокета, и принимает его, в противном случае он добавляет задачу в очередь, которая будет обрабатываться пулом потоков, как только поток станет доступным. для обработки ввода-вывода с клиентами. Все это работает, однако я не могу добиться динамического увеличения размера полученного буфера.
Проблема этой реализации заключается в том, что всякий раз, когда длина полученного ввода равна кратен максимальному размеру буфера, заданному функции Recv(), цикл всегда ждет следующего отправленного сообщения.
Функция получателя следующая:

Код: Выделить всё

static void do_recv(int fd) {
char rbuf[MAX_RECV_BUFFER_SIZE] = {0};
int n = -1;
while (1) {
n = recv(fd, rbuf, sizeof(rbuf), MSG_DONTWAIT);
if (n > 0) {
// each client when the connection is accepted gets a NULL buffer to recieve their data
extend_rbuf(fd, rbuf, n, sizeof(rbuf));
std::cout size = client_rbuf->len + rlen + 1;
char *new_rbuf = (char *)realloc(client_rbuf->buf, client_rbuf->size * sizeof(char));
if (!new_rbuf) {
perror("realloc new_rbuf: out of memory");
}
client_rbuf->buf = new_rbuf;
memcpy(client_rbuf->buf + client_rbuf->len, data, rlen);
client_rbuf->len += rlen;
}
return 0;
}
Условие, вызывающее проблему:

Код: Выделить всё

if (n == sizeof(rbuf)) {
continue;
}
Чтобы протестировать этот подход, я установил для MAX_RECV_BUFFER_SIZE значение 2. Проблема в том, что когда я отправляю сообщение длины l, такое что l mod 2 = 1, а затем «читаю завершено здесь", например, если я отправлю ввод 123 с помощью telnet (я думаю, telnet добавляет \r\n), программа напечатает это:

Код: Выделить всё

bytes read: 2 current read: 12
size: 3 len: 2
bytes read: 2 current read: 3
size: 5 len: 4
bytes read: 1 current read:

size: 6 len: 5
read ended here, read from client
123

Однако если входные данные имеют длину 4, например 1234, то выходные данные будут такими:

Код: Выделить всё

bytes read: 2 current read: 12
size: 3 len: 2
bytes read: 2 current read: 34
size: 5 len: 4
bytes read: 2 current read:

size: 7 len: 6
и я получу сообщение 1234 только в том случае, если отправлю другое сообщение нечетной длины, например отправив o, тогда я получу сейчас

Код: Выделить всё

bytes read: 2 current read: o
size: 9 len: 8
bytes read: 1 current read:

size: 10 len: 9
read ended here, read from client
1234 # 1234 shows up here now
o

Есть ли способ сделать это по-другому?

Подробнее здесь: https://stackoverflow.com/questions/790 ... uffer-size
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»