Я использую загрузку файлов на основе http в своем коде c ++ (работает на Linux / Android). Я использую асинхронный сокет TCP для записи данных файла. Моя проблема в том, что мой индикатор выполнения отображает то, что было записано в сокет, а не то, что было отправлено по проводам. Проблема становится очевидной с медленными ссылками, где требуется от десятков секунд (иногда больше минуты) между 100% отправленным уведомлением о ходе выполнения и отправкой полного сообщения.
Я не изменяю SO_SNDBUF, в моем случае это 35 КБ (по запросу getsockopt). Как я могу исправить уведомление о прогрессе, чтобы правильно отразить текущий статус передачи? Есть ли способ запросить размер данных, которые все еще остаются в буфере? Есть ли способ получить уведомление TCP о ходе передачи (что подтверждается удаленным сокетом)?
Вы не сможете узнать текущий размер этого буфера, потому что он находится на земле ядра, и нет никакого известного / документированного ioctl, чтобы определить его размер. Даже вы могли бы знать, что он вообще не будет переносимым, поэтому я не думаю, что это хороший способ решить эту проблему.
Вы также можете:
Оцените скорость передачи данных в течение всей передачи, чтобы в конце вычислить время, оставшееся для этого буфера SO_SNDBUF.
Используйте стороннюю библиотеку, которая будет включать в себя предыдущие вычисления!
РЕДАКТИРОВАТЬ: После некоторых исследований в книге TCP/IP Architecture, Design & Implementation in Linux
Я видел NETLINK_TCPDIAG
опция для мониторинга сокетов TCP. Netlink сокеты — это метод IPC между ядром и землей пользователя. Для NETLINK_TCPDIAG
Опция, к сожалению, здесь нет деталей … Я просто знаю, что вы должны создать сокет, как это: int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_TCPDIAG)
а для создания сырых сокетов нужны привилегии суперпользователя.
После этого ваш единственный друг, кажется, linux/net/ipv4/tcp_diag.c
(http://www.cs.fsu.edu/~baker/devices/lxr/http/ident?v=2.6.11.8;i=NETLINK_TCPDIAG) … В Google нет ничего про этот тип протокола … Удачи!