Если у вас NODELAY = false (это значение по умолчанию), когда вы вызываете send () с меньшим количеством байтов, чем в окне TCP, байты на самом деле не отправляются немедленно, поэтому вы правы. ОС немного подождет, чтобы узнать, вызовете ли вы другой send (), чтобы использовать только один пакет для передачи объединенных данных и избежать потери заголовка TCP.
Когда NODELAY = true, данные передаются при вызове send (), поэтому вы можете (теоретически) рассчитывать на возвращаемое значение. Но это не рекомендуется из-за дополнительной неэффективности сети.
В общем, если вам не нужна абсолютная точность, вы можете использовать значение, возвращаемое send (), даже когда NODELAY = true. Это значение не будет отражать непосредственную реальность, но через несколько миллисекунд оно будет изменяться (но также будет проверяться наличие потерянных соединений, поскольку последний отправленный вами блок данных мог быть потерян). Как только соединение будет корректно разорвано, вы можете доверять всем данным, которые были переданы. Если это не так, вы узнаете об этом раньше - либо из-за того, что соединение было внезапно прервано, либо из-за того, что вы получили ошибку, связанную с хранением данных (или любую другую).