Как проверить емкость буфера отправки TCP для обеспечения доставки данных - PullRequest
0 голосов
/ 06 декабря 2011

Я хотел бы добавить подтверждение доставки в мой интерфейс TCP.Неблокирующая запись может заполнить буфер отправки, но данные могут никогда не прийти, если соединение не установится - тем временем запись сообщила, что данные были получены (локальным сокетом).

Если я добавил дополнительные подтверждения встек, я мог убедиться, что каждый кусок данных был получен.Я думаю, что FTP делает это.Но я не могу заимствовать чей-либо код и предпочел бы не реализовывать ack / resend, особенно потому, что TCP уже делает большую часть этого.

Я думаю, что это можно сделать, если я смогу проверить, что буфер отправки сокета пусткаждая запись ().Если данных больше нет, все должно быть доставлено.Я не возражаю против задержки очистки буфера.

Редактировать: я понимаю, реализации TCP / сокетов различаются в зависимости от системы, но если есть решение Беркли или Linux, оно, вероятно, доступно для меня.

Редактировать: Чтобы ответить на некоторые предложения, я хотел бы реализовать три уровня интерфейса TCP, где я не знаю, как выполнить * 'd.

  • Обычный TCP без гарантии доставкидля приложений, которым нравится опасно жить.
  • * TCP, который проверяет получение удаленным хостом, даже если пакет никогда не доставлялся удаленному приложению.Это снижает большую часть моего риска соединения (мобильный клиент) и может быть полностью реализовано на стороне клиента.Я думаю, что это может быть реализовано, если я смогу проверить, что исходящий буфер сокета пуст.
  • ACK прикладного уровня и повторная отправка реализованы поверх TCP или UDP, поэтому конечные точки проверены.

Ответы [ 2 ]

9 голосов
/ 06 декабря 2011

На самом деле проверять вещи на уровне приложения - единственный способ . Вот несколько вопросов:

  • Когда вы send данных, даже если они покидают ваше ядро, это не будет сделано, пока ваш TCP не получит ACK об этом. API не предоставляет вам эту информацию .

  • Тот факт, что ваша заявка получила ACK, может означать:

    • Удаленное ядро ​​( не приложение ) получило данные. Нельзя сказать, если удаленный процесс называется recv. Возможно, он падает до того, как получит шанс recv.
    • Некоторые прокси-серверы (МНОГИЕ дешевые устройства делают это) разговаривают с вами и используют отдельное соединение с истинным получателем. Вы получили ACK, но не знаете, есть ли в удаленной системе. А если он есть в удаленной системе, прочитайте вышеупомянутый пункт.

В заключение:

  • У вас нет доступа к TCP ACK s
  • Даже если бы вы имели к ним доступ, они были бы бесполезны

Итак, вам нужен ACK уровня приложения, но, конечно, без повторных передач . ACK должен просто сказать вам: «Я получил и обработал ваши данные».

EDIT

Я вижу тебя настойчивым в твоей идее. Найдите SIOCOUTQ, как описано на нескольких страницах руководства Linux. Конечно, это только для Linux, но посмотрите, делает ли он то, что вам нужно.

2 голосов
/ 06 декабря 2011

TCP обеспечивает только доставку на уровне ОС. Это означает, например, что если ваше приложение-получатель неожиданно завершает работу во время передачи, ваш отправитель не может быть уверен, что все данные получены - подумайте, когда удаленный стек TCP отправляет подтверждение о полученных данных, но ваше приложение этого не делает. получите возможность обработать эти данные.

Вот почему вам может понадобиться схема подтверждения на уровне приложения. Например, вы можете использовать ту же технику, что и в стеке TCP - использовать ack-номера, только на этот раз на уровне приложения. Если ваше удаленное приложение отправляет вам подтверждающий номер X, вы можете быть уверены, что элементы данных X действительно получены и обработаны приложением , а не стеком TCP ОС .

...