Здравствуйте, нужно сделать UDP сервер-клиент для передачи больших файлов. Стандартный вариант я так понимаю выглядит примерно следующим образом: "сервер послал блок пакетов->ждет ответа от клиента->получил ответ, послал следующий блок", вариаций этой структуры может быть много, но суть одна — сервер с разной периодичностью должен ожидать подтверждений от клиента. Стоит ли заморачиваться на системе без ожиданий или же подобная система может пошатнуть надежность передачи(ведь клиент может, допустим, стоять на очень слабой машине по отношению к серверу или же по неосторожности включим какой-нибудь фаервол, который заблокирует 1000 пакетов)?
Здравствуйте, Ifrin, Вы писали:
I>Здравствуйте, нужно сделать UDP сервер-клиент для передачи больших файлов. Стандартный вариант я так понимаю выглядит примерно следующим образом: "сервер послал блок пакетов->ждет ответа от клиента->получил ответ, послал следующий блок", вариаций этой структуры может быть много, но суть одна — сервер с разной периодичностью должен ожидать подтверждений от клиента. Стоит ли заморачиваться на системе без ожиданий или же подобная система может пошатнуть надежность передачи(ведь клиент может, допустим, стоять на очень слабой машине по отношению к серверу или же по неосторожности включим какой-нибудь фаервол, который заблокирует 1000 пакетов)?
В нормально работающем интернете теряется 1-2% пакетов. Если случается какая-то неисправность, потери могут быть гораздо больше. Поэтому пытаться передавать большой файл без контроля доставки и досылки недошедшего — неразумно (можно использовать кодирование с избыточностью, но надо понимать, что если оно у вас передает, к примеру, блоками из 5-и пакетов, и выдерживает потерю одного пакета из блока, то это уменьшает количество недошедших блоков в 5 раз, а не в миллион, т.е. на большом файле все равно будут потери и потребуется retransmit).
I>ЗЫ: TCP не предлагать)
Почему? TCP лучше во многих отношениях. Например, есть полно контор, где UDP траффик закрыт наружу вообще, и ничего вы по UDP в/из такой конторы не передадите.
Здравствуйте, Pzz, Вы писали:
Pzz>В нормально работающем интернете теряется 1-2% пакетов. Если случается какая-то неисправность, потери могут быть гораздо больше. Поэтому пытаться передавать большой файл без контроля доставки и досылки недошедшего — неразумно (можно использовать кодирование с избыточностью, но надо понимать, что если оно у вас передает, к примеру, блоками из 5-и пакетов, и выдерживает потерю одного пакета из блока, то это уменьшает количество недошедших блоков в 5 раз, а не в миллион, т.е. на большом файле все равно будут потери и потребуется retransmit).
Ну досылку делать надо это да, у меня скорее вопрос заключается немного в другом.
Например система вида: "сервер постоянно шлет пакеты-> клиент постоянно считывает, каким-то образом определяет недошедшие и отправляет сообщение серверу о потерях-> сервер вместе с обычными пакетами шлет недошедшие". То есть сервер находиться в постоянной пересылке, он не ожидает ответа об отдельных блоках пакетов от клиента. Тогда взглянем на следующую ситуацию: сервер отправляет пакеты, неожиданно появился сбой и 1000 были уничтожены, он отправил 1001 пакет и продолжает передачу дальше, не зная что предыдущие не дошли до клиента, клиент принял 1001 пакет и заметил, что не хватает 1000 пакетов. Дальше единственный выход, это сказать серверу что бы тот остановился(за это время сервером может быть отправлено еще 100 пакетов) и начать передавать ему информацию о потерянных пакетах, что тоже довольно проблематично, т.к. некоторые из них могут опять потеряться)
Собственно вопрос в том, стоит ли пытаться сделать что-нибудь на основе подобной системы или же лучше остановиться на стандартной.
Pzz>Почему? TCP лучше во многих отношениях. Например, есть полно контор, где UDP траффик закрыт наружу вообще, и ничего вы по UDP в/из такой конторы не передадите.
Да я понимаю что лучше, просто надо именно UDP.
Здравствуйте, Ifrin, Вы писали:
I>Ну досылку делать надо это да, у меня скорее вопрос заключается немного в другом. I>Например система вида: "сервер постоянно шлет пакеты-> клиент постоянно считывает, каким-то образом определяет недошедшие и отправляет сообщение серверу о потерях-> сервер вместе с обычными пакетами шлет недошедшие". То есть сервер находиться в постоянной пересылке, он не ожидает ответа об отдельных блоках пакетов от клиента. Тогда взглянем на следующую ситуацию: сервер отправляет пакеты, неожиданно появился сбой и 1000 были уничтожены, он отправил 1001 пакет и продолжает передачу дальше, не зная что предыдущие не дошли до клиента, клиент принял 1001 пакет и заметил, что не хватает 1000 пакетов. Дальше единственный выход, это сказать серверу что бы тот остановился(за это время сервером может быть отправлено еще 100 пакетов) и начать передавать ему информацию о потерянных пакетах, что тоже довольно проблематично, т.к. некоторые из них могут опять потеряться)
Нет, это плохо. Вы можете начать посылать пакеты быстрее, чем они в сеть пролазят. Надо обязательно делать congestion control. Т.е., сервер может послать N пакетов, но пока он не получил от клиента подтверждение о том, что сколько-то из них дошло до клиента, он должен притормозить и ждать. Выражаясь чуть точнее, сервер должен стремиться поддерживать такое состояние, когда не более, чем N пакетов болтаются "в воздухе", т.е. он их послал, но еще не знает, дошли они, или нет. Чему равно N — тоже хороший вопрос, в TCP этот параметр меняется динамически по довольно нетривиальному алгоритму. N должно быть достаточно велико, чтобы сервер не останавливался из-за большого round-trip-time, но не настолько большим, чтобы заливать роутеры по дороге.
Пакеты могут приходить не в том порядке, в котором они были отправлены. Правда, это в реальных интернетах бывает не так уж и часто, тоже где-то в районе 1%. Это желательно учитывать. Т.е., если клиент получил 11-й пакет, не получив 10-го, прежде, чем требовать ретрансмита, есть смысл немного подождать, вдруг 10-й пакет просто заскочил по дороге пропустить рюмашечку и придет чуть позже.
Перепосылку лучше делать селективную. Т.е., если не дошел пакет с номером 10, а сервер уже послал 20 пакетов, лучше бы перепослать только 10-й, а не все с 10-го по 20-й.
Ну и наконец, надо не забывать, что ответы клиента тоже могут теряться. Алгоритм должен уметь восстанавливаться из такой ситуации, а не ждать потерянного ответа до морковкина заговения.
I>Собственно вопрос в том, стоит ли пытаться сделать что-нибудь на основе подобной системы или же лучше остановиться на стандартной.
Pzz>>Почему? TCP лучше во многих отношениях. Например, есть полно контор, где UDP траффик закрыт наружу вообще, и ничего вы по UDP в/из такой конторы не передадите. I>Да я понимаю что лучше, просто надо именно UDP.
Ну приоткройте всеж завесы тайны, откуда такое требование?
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, Ifrin, Вы писали:
Pzz>Нет, это плохо. Вы можете начать посылать пакеты быстрее, чем они в сеть пролазят. Надо обязательно делать congestion control. Т.е., сервер может послать N пакетов, но пока он не получил от клиента подтверждение о том, что сколько-то из них дошло до клиента, он должен притормозить и ждать. Выражаясь чуть точнее, сервер должен стремиться поддерживать такое состояние, когда не более, чем N пакетов болтаются "в воздухе", т.е. он их послал, но еще не знает, дошли они, или нет. Чему равно N — тоже хороший вопрос, в TCP этот параметр меняется динамически по довольно нетривиальному алгоритму. N должно быть достаточно велико, чтобы сервер не останавливался из-за большого round-trip-time, но не настолько большим, чтобы заливать роутеры по дороге.
Спасибо, того остановлюсь на стандарте.
Pzz>Ну приоткройте всеж завесы тайны, откуда такое требование?
Не думаю что это особо принципиально, просто "приказали" сделать UDP, вот и делаю)
Здравствуйте, Ifrin, Вы писали:
Pzz>>Ну приоткройте всеж завесы тайны, откуда такое требование? I>Не думаю что это особо принципиально, просто "приказали" сделать UDP, вот и делаю)
Я бы подумал о том, чтобы используя UDP как транспорт, пустить поверх него настоящий TCP. Потому что иначе кончится тем, что вы напишете самодельный TCP, который будет работать в 100 раз хуже настоящего.
Между прочим, роутеры в "большом интернете" не рассчитаны на чрезмерное количество UDP-траффика. Когда uTorrent перешел на UDP, магистральные провайдеры стали тихо скулить, потому что их цискам сплохело.
"Ifrin" <92285@users.rsdn.ru> wrote in message news:4045228@news.rsdn.ru... > Здравствуйте, нужно сделать UDP сервер-клиент для передачи больших файлов.
Вы, кстати, забыли уточнить — речь идет об интернете или локальной сети? Пользователи домашние или корпоративные?
Есть хорошая подбока статей про программирование сети для игр от Glenn Fiedler. Если откинуть требование soft real time, то бОльшая часть статистики ("The Internet Sucks", Networking for Physics Programmers) и выводов подойдет и для вашего случая.
Re: Надежный UDP сервер
От:
Аноним
Дата:
19.11.10 19:03
Оценка:
Здравствуйте, Ifrin, Вы писали:
I>Здравствуйте, нужно сделать UDP сервер-клиент для передачи больших файлов. Стандартный вариант я так понимаю выглядит примерно следующим образом: "сервер послал блок пакетов->ждет ответа от клиента->получил ответ, послал следующий блок", вариаций этой структуры может быть много, но суть одна — сервер с разной периодичностью должен ожидать подтверждений от клиента. Стоит ли заморачиваться на системе без ожиданий или же подобная система может пошатнуть надежность передачи(ведь клиент может, допустим, стоять на очень слабой машине по отношению к серверу или же по неосторожности включим какой-нибудь фаервол, который заблокирует 1000 пакетов)?
I>ЗЫ: TCP не предлагать)
Мы в свое время, нае...лись с этим, много человека месяцев ушло на это. Пробовали различные готовые библиотеки на эту тему.
Теперь зато я досконально знаю TCP
Готовся к тому, что это не простая задача.
И не забудь что главное не написать, а самое главное отладить потом этот код, и разобраться например почему в одних ситуациях он хорошо работает, а в других очень плохо !!!
А иногда виснит, и очень редко, что повторять замучаешься...
Pzz>Я бы подумал о том, чтобы используя UDP как транспорт, пустить поверх него настоящий TCP. Потому что иначе кончится тем, что вы напишете самодельный TCP, который будет работать в 100 раз хуже настоящего.
Здравствуйте, maks1180, Вы писали:
Pzz>>Я бы подумал о том, чтобы используя UDP как транспорт, пустить поверх него настоящий TCP. Потому что иначе кончится тем, что вы напишете самодельный TCP, который будет работать в 100 раз хуже настоящего.
M>А как это реализовать можно ?
Ну, например, можно туннелировать IP через UDP, а поверх запустить родной системный TCP-стек. А можно взять какую-нибудь userspace реализацию TCP (в виде библиотеки) и подсунуть ему в качестве пакетного транспорта свою функцию, которая будет передавать пакеты с помощью UDP.
Кстати, если TCP не попадется, можно взять SCTP, он ничем не хуже.
Pzz>>>Я бы подумал о том, чтобы используя UDP как транспорт, пустить поверх него настоящий TCP. Потому что иначе кончится тем, что вы напишете самодельный TCP, который будет работать в 100 раз хуже настоящего.
M>>А как это реализовать можно ?
Pzz>Ну, например, можно туннелировать IP через UDP, а поверх запустить родной системный TCP-стек.
это же только через драйвер можно ?
А можно взять какую-нибудь userspace реализацию TCP (в виде библиотеки) и подсунуть ему в качестве пакетного транспорта свою функцию, которая будет передавать пакеты с помощью UDP.
Какую например ?
Pzz>Кстати, если TCP не попадется, можно взять SCTP, он ничем не хуже.
Здравствуйте, maks1180, Вы писали:
Pzz>>Ну, например, можно туннелировать IP через UDP, а поверх запустить родной системный TCP-стек. M>это же только через драйвер можно ?
Да.
M>А можно взять какую-нибудь userspace реализацию TCP (в виде библиотеки) и подсунуть ему в качестве пакетного транспорта свою функцию, которая будет передавать пакеты с помощью UDP. M>Какую например ?
А вот это хороший вопрос. Ищите, их должно быть, трудно сказать, какого качества.
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, maks1180, Вы писали:
Pzz>>>Ну, например, можно туннелировать IP через UDP, а поверх запустить родной системный TCP-стек. M>>это же только через драйвер можно ?
Pzz>Да.
M>>А можно взять какую-нибудь userspace реализацию TCP (в виде библиотеки) и подсунуть ему в качестве пакетного транспорта свою функцию, которая будет передавать пакеты с помощью UDP. M>>Какую например ?
Pzz>А вот это хороший вопрос. Ищите, их должно быть, трудно сказать, какого качества.
Искали, очень примитивные, т.е. много чего не реализовано что есть в TCP (SACK и т.д.) и качество плохое...
Здравствуйте, Ifrin, Вы писали:
I>Здравствуйте, нужно сделать UDP сервер-клиент для передачи больших файлов.
Если задача практическая, а не академическая, то поднимите OpenVPN (он по умочанию по UDP работает) и поверх него пускайте любой траффик, хоть FTP или HTTP. Иначе придется реализовывать свой собственный TCP/IP с преферансом и барышнями.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Здравствуйте, Ifrin, Вы писали:
I>Здравствуйте, нужно сделать UDP сервер-клиент для передачи больших файлов. Стандартный вариант я так понимаю выглядит примерно следующим образом: "сервер послал блок пакетов->ждет ответа от клиента->получил ответ, послал следующий блок", вариаций этой структуры может быть много, но суть одна — сервер с разной периодичностью должен ожидать подтверждений от клиента. Стоит ли заморачиваться на системе без ожиданий или же подобная система может пошатнуть надежность передачи(ведь клиент может, допустим, стоять на очень слабой машине по отношению к серверу или же по неосторожности включим какой-нибудь фаервол, который заблокирует 1000 пакетов)?
I>ЗЫ: TCP не предлагать)
хе-хе,
вы спросили как написать самому TCP и добавили "TCP не предлагать)"