README на английском языке
KCP — это быстрый и надежный протокол, который может сократить среднюю задержку на 30–40 % и уменьшить максимальную задержку в три раза за счет увеличения пропускной способности на 10–20 % по сравнению с TCP. Реализация чистого алгоритма не отвечает за отправку и получение базовых протоколов (таких как UDP). Пользователям необходимо определить метод отправки пакетов данных нижнего уровня и предоставить его KCP в форме обратного вызова. Даже часы необходимо передать извне, и никаких внутренних вызовов не будет.
Весь протокол имеет только два исходных файла: ikcp.h и ikcp.c, которые можно легко интегрировать в собственный стек протоколов пользователя. Возможно, вы реализовали протокол на основе P2P или UDP, но у вас нет полной и надежной реализации протокола ARQ. Тогда просто скопируйте эти два файла в существующий проект, напишите несколько строк кода, и вы сможете его использовать.
TCP предназначен для трафика (сколько КБ данных может быть передано в секунду), и упор делается на полное использование полосы пропускания. KCP рассчитан на скорость потока (сколько времени требуется для отправки одного пакета данных с одного конца на другой). Он обменивает 10–20% потери полосы пропускания на скорость передачи, которая на 30–40% выше, чем TCP). . Канал TCP представляет собой большой канал с медленной скоростью течения, но с большой скоростью потока в секунду, тогда как канал KCP представляет собой небольшой порог с быстрым течением. ККП имеет два типа: нормальный режим и быстрый режим. Результат увеличения скорости потока достигается за счет следующих стратегий:
Расчет таймаута TCP — RTOx2. Если вы потеряете три пакета подряд, он станет RTOx8, что очень страшно. Однако после запуска KCP быстрого режима он становится не х2, а всего лишь х1,5 (эксперименты доказали это). значение 1,5 относительно хорошее), что улучшает скорость передачи.
Когда TCP теряет пакет, он повторно передает все данные, начиная с потерянного пакета. KCP выполняет повторную передачу выборочно и повторно передает только действительно потерянные пакеты данных.
Отправитель отправил несколько пакетов 1, 2, 3, 4 и 5, а затем получил ACK от удаленного конца: 1, 3, 4, 5. При получении ACK3 KCP знал, что 2 был пропущен один раз, и получил, когда ACK4. получен, известно, что пакет 2 был пропущен дважды. В это время можно считать, что пакет номер 2 потерян. Нет необходимости ждать тайм-аута, и пакет номер 2 можно передать напрямую, что значительно улучшается. скорость передачи при потере пакетов.
Чтобы полностью использовать пропускную способность, TCP задерживает отправку ACK (NODELAY бесполезен). Таким образом, при расчете таймаута будет рассчитано большее время RTT, что продлит процесс принятия решения в случае потери пакета. Можно настроить, будет ли отправлено подтверждение KCP с задержкой.
Существует два типа ответов модели ARQ: UNA (все пакеты до этого номера были получены, например TCP) и ACK (пакеты с этим номером были получены). Использование только UNA вызовет все повторные передачи, а использование только ACK приведет к повторной передаче. слишком высокая стоимость потерь. В прошлом все протоколы предполагали выбор одного из двух, но в протоколе KCP, за исключением отдельных пакетов ACK, все пакеты содержат информацию UNA.
В обычном режиме KCP используется то же правило справедливой уступки, что и в TCP, то есть размер окна отправки определяется четырьмя факторами: размером буфера отправки, оставшимся размером буфера приема на принимающей стороне, уступкой при потере пакетов и медленным запуском. Однако при передаче небольших данных с высокими требованиями к своевременности вы можете пропустить последние два шага настройки и использовать только первые два пункта для управления частотой отправки. За счет частичной справедливости и использования полосы пропускания эффект плавной передачи может быть достигнут даже при включении BT.
Вы можете скачать и установить kcp с помощью менеджера библиотек vcpkg:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install kcp
Библиотека kcp в vcpkg постоянно обновляется членами команды Microsoft и участниками сообщества. Если версия устарела, создайте проблему или подайте запрос в репозиторий vcpkg.
Создайте объект KCP:
// 初始化 kcp对象,conv为一个表示会话编号的整数,和tcp的 conv一样,通信双
// 方需保证 conv相同,相互的数据包才能够被认可,user是一个给回调函数的指针
ikcpcb *kcp = ikcp_create(conv, user);
Установить функцию обратного вызова:
// KCP的下层协议输出函数,KCP需要发送数据时会调用它
// buf/len 表示缓存和长度
// user指针为 kcp对象创建时传入的值,用于区别多个 KCP对象
int udp_output ( const char *buf, int len, ikcpcb *kcp, void *user)
{
....
}
// 设置回调函数
kcp->output = udp_output;
Вызов обновления в цикле:
// 以一定频率调用 ikcp_update来更新 kcp状态,并且传入当前时钟(毫秒单位)
// 如 10ms调用一次,或用 ikcp_check确定下次调用 update的时间不必每次调用
ikcp_update (kcp, millisec);
Введите пакет нижнего уровня:
// 收到一个下层数据包(比如UDP包)时需要调用:
ikcp_input (kcp, received_udp_packet, received_udp_size);
После обработки вывода/ввода протокола нижнего уровня протокол KCP может работать нормально. Используйте ikcp_send для отправки данных на удаленный конец. Другой конец использует ikcp_recv(kcp, ptr, size) для получения данных.
Режим протокола по умолчанию — стандартный ARQ, и при настройке необходимо включить различные переключатели ускорения:
Режим работы:
int ikcp_nodelay (ikcpcb *kcp, int nodelay, int interval, int resend, int nc)
Максимальное окно:
int ikcp_wndsize (ikcpcb *kcp, int sndwnd, int rcvwnd);
Этот вызов установит максимальное окно отправки и максимальный размер окна приема протокола, который по умолчанию равен 32. Это можно понимать как SND_BUF и RCV_BUF TCP, но единицы измерения разные. Единица SND/RCV_BUF — это байты, а эта единица — байты. пакеты.
Максимальная единица передачи:
Протокол чистого алгоритма не отвечает за определение MTU. Значение MTU по умолчанию составляет 1400 байт. Для установки этого значения можно использовать ikcp_setmtu. Это значение повлияет на максимальную единицу передачи при объединении и фрагментации пакетов данных.
Минимальное RTO:
Независимо от того, TCP или KCP, при расчете RTO существует минимальный предел RTO. Даже если расчетное значение RTO составляет 40 мс, поскольку значение RTO по умолчанию составляет 100 мс, протокол может обнаружить потерю пакетов только через 100 мс. В быстром режиме оно составляет 30 мс. Это значение можно изменить вручную:
kcp->rx_minrto = 10 ;
Использование и настройка протокола очень просты. В большинстве случаев вы можете использовать его после прочтения приведенного выше содержимого. Если вам нужен более детальный контроль, например, изменение распределителя памяти KCP, или вам нужно более эффективно планировать соединения KCP в большом масштабе (например, более 3500), или как лучше интегрироваться с TCP, вы можете продолжить чтение:
Связанное чтение: «Genshin Impact» также использует KCP для ускорения новостей об игре.
KCP успешно использовался в нескольких проектах с сотнями миллионов пользователей, обеспечивая им более отзывчивую и бесперебойную работу сети.
Добро пожаловать, чтобы рассказать нам больше случаев
Если сеть никогда не зависает, то KCP/TCP будет вести себя аналогично, но сама сеть ненадежна, а потеря пакетов и джиттер неизбежны (иначе зачем нам различные надежные протоколы)? При прямом сравнении в почти идеальной среде, такой как интрасеть, все практически одинаковы. Однако при размещении в общедоступной сети, сети 3G/4G или при моделировании потери пакетов в интрасети разрыв становится очевидным. В общедоступной сети средняя потеря пакетов составляет около 10% в периоды пиковой нагрузки, а в сетях Wi-Fi/3g/4g ситуация еще хуже, что приводит к задержкам передачи.
Спасибо автору asio-kcp zhangyuan за горизонтальную оценку KCP, enet и udt. Выводы такие:
Подробнее см.: Данные горизонтального сравнения и оценки дают дополнительные рекомендации для тех, кто колеблется в выборе.
Серверный движок SpatialOS для массовой многопользовательской игры получил ту же оценку, что и TCP/RakNet, после интеграции протокола KCP:
Мы сравнили время отклика при одновременном поддержании 50 символов с частотой обновления 60 Гц на стороне сервера. См. подробный отчет о сравнении:
В последние годы онлайн-игры и различные социальные сети выросли в геометрической прогрессии. Независимо от онлайн-игр или различных интерактивных социальных сетей, интерактивность и сложность быстро растут, и всем им необходимо доставлять данные одновременно и за очень короткое время. пользователей, технология передачи, естественно, станет важным фактором, ограничивающим будущее развитие, и различные известные протоколы передачи в мире с открытым исходным кодом, такие как raknet/enet Например, при выпуске выпускается весь стек протоколов вместе. Такая форма не способствует диверсификации. Мой проект может только выбирать, использовать вас или нет. Трудно выбрать «частично использовать вас», но вы проектируете. набор стеков протоколов, каким бы хорошим он ни был, очень сложно удовлетворить различные потребности с разных сторон.
Поэтому метод KCP заключается в том, чтобы «разобрать» стек протоколов, чтобы каждый мог гибко настроить и собрать его в соответствии с потребностями проекта. Вы можете добавить слой стирающего кода Рида-Соломона ниже для FEC и слой над ним для RC4/Salsa20. Для потокового шифрования во время рукопожатия разработан асимметричный обмен ключами, а на базовом транспортном уровне UDP создается система динамической маршрутизации для одновременного обнаружения нескольких путей и выбора наилучшего пути для передачи. Эти различные «единицы протокола» можно свободно комбинировать по мере необходимости, как строительные блоки, чтобы обеспечить «простоту» и «отключаемость», чтобы они могли гибко адаптироваться к меняющимся потребностям бизнеса. Если какой-либо модуль не подходит, просто замените его.
Будущие решения передачи должны быть глубоко адаптированы в соответствии со сценариями использования, поэтому мы предоставляем каждому «блок протокола», который можно свободно комбинировать для облегчения интеграции в ваш собственный стек протоколов.
Для получения дополнительной информации см. Истории успеха.
Автор: Линь Вэй (skywind3000)
Добро пожаловать, подписывайтесь на меня в личном блоге и Twitter.
В течение моего многолетнего опыта разработки мне всегда нравилось изучать и решать некоторые узкие места в программах. В ранние годы мне нравилась разработка игр, чтобы заниматься игровой графикой, и я читал «Графическую программу» Майкла Абраша. Руководство разработчика» для выполнения мягкого рендеринга. Мне нравится экспериментировать с кодом, который может выжать процессор и работать быстрее. После того, как я присоединился к работе, мой интерес сместился в сторону серверных и сетевых технологий.
В 2007 году, после создания нескольких традиционных игр, я начал изучать проблему синхронизации в играх с быстрым действием. За этот период я написал много статей и был одним из первых, кто начал изучать проблемы синхронизации. как бы ни решить синхронизацию, нам нужно что-то сделать с точки зрения сетевой передачи. Выйдя из игры и переключившись на Интернет, я также обнаружил, что во многих полях есть такая необходимость, поэтому я начал тратить время на область сетевой передачи. , пытаясь реализовать некоторые консервативные и надежные протоколы на основе UDP и имитируя код BSD Lite 4.4 для реализации некоторых TCP-подобных протоколов. Протокол мне показался весьма интересным, а затем я реализовал некоторые игрушки, связанные с P2P и сетями динамической маршрутизации. Протокол KCP родился в 2011 году. По сути, это одна из нескольких игрушек, созданных самостоятельно с точки зрения передачи.
Автор Kcptun, xtaci, мой однокурсник по колледжу. Мы оба специализируемся на коммуникациях и часто вместе изучаем, как оптимизировать передачу.
Добро пожаловать в Alipay, чтобы отсканировать приведенный выше QR-код и сделать пожертвование на этот проект. Пожертвования будут использоваться для постоянной оптимизации протокола KCP и улучшения документации.
Благодарность: Минмин, Синцзы, Цзинь, Фань, Яньчжао, Биньцюань, Сяодань, Юй Чжэн, Ху, Шэнган, Сюй Вэй, Ван Чуань, Чжао Ганцян, Ху Чжифэн, Ван Синьчао, Хэ Синьчао, Лю Ян, Хоу Сяньхуэй, У Пейи , Хуа Бинь, Рутао, Ху Цзянь. . . (извините, что не записала предыдущий список) Ждем пожертвований и поддержки от одноклассников.
Добро пожаловать, обратите внимание
Группа связи KCP: 364933586 (номер группы QQ), интеграция KCP, настройка, передача по сети и соответствующие технические обсуждения.
Группа Гиттера: https://gitter.im/skywind3000/KCP
блог: http://www.skywind.me
Этот проект существует благодаря всем людям, которые вносят свой вклад.