send () и write () в выходной буфер TCP, который заполнен, не блокируется

Я сталкиваюсь с проблемой простой функции (язык C ++), которая перебирает список объектов, сериализует их и отправляет на удаленный сервер. Я выполняю эту функцию на плате ESP32, которая работает с FreeRTOS и LwIP, поэтому у меня есть выходной буфер TCP, который по умолчанию ограничен 5744 байтами (я могу настроить его, но я не хочу использовать более 10-15 тысяч байтов) ,

По сути, это то, что происходит: я вызываю несколько раз (обычно 200-300 раз) write () или send () для сокета, каждый раз записывая ~ 1400 байт. Через некоторое время, если сервер на другой стороне немного медленный, я насыщаю выходной буфер TCP. Теперь, насколько я понимаю, send () или write () должны подождать, пока появится место для повторной записи данных в сокет, но вместо этого функция немедленно возвращает значение, отличное от значения, которое я хотела записать (скажем, 1400 байт). ).

char buffer[1460];
result = write(current_socket, buffer, 1460);
if(result != 1460){
    // error
} else {
    // everything ok
}

Сокет используется по умолчанию, поэтому он является блокирующим сокетом, и никакие параметры не указаны. Я хотел бы, чтобы запись блокировалась, пока не будет достаточно места для записи всех 1460 байтов, указанных в коде выше. Единственной причиной, по которой запись должна вернуть ошибку, должен быть сбой на другой стороне, например, сервер закрывает сокет. Это возможно?

Всего 1 ответ


То, что вы видите, называется частичной записью . Это нормально для TCP.

Когда буфер частично заполнен, вызов для write копирует столько данных, сколько уместится, и возвращает количество байтов, скопированных в буфер. Это ваша работа, чтобы иметь дело с остальными данными позже.

Для того, чтобы отправить ваш буфер данных, вам нужно выполнить цикл, пока буфер не будет пустым:

buf_ptr = 0;
buf_end = 1460;
while(buf_ptr < buf_end) {
    rc = write(fd, buf + buf_ptr, buf_end - buf_ptr);
    if(rc <= 0)
        break
    buf_ptr += rc;
}

Есть идеи?

10000