93 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Markdown
		
	
	
			
		
		
	
	
			93 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Markdown
		
	
	
# Протокол mKCP
 | 
						||
 | 
						||
mKCP - это потоковый транспортный протокол, основанный на [протоколе KCP](https://github.com/skywind3000/kcp), который может передавать любые потоки данных по порядку.
 | 
						||
 | 
						||
## Версия
 | 
						||
 | 
						||
Протокол mKCP не имеет номера версии, совместимость между версиями не гарантируется.
 | 
						||
 | 
						||
## Зависимости
 | 
						||
 | 
						||
### Базовый протокол
 | 
						||
 | 
						||
mKCP - это протокол, основанный на UDP, все коммуникации осуществляются по UDP.
 | 
						||
 | 
						||
### Функции
 | 
						||
 | 
						||
- fnv: хэш-функция [FNV-1a](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function)
 | 
						||
  - Входные данные: строка произвольной длины;
 | 
						||
  - Выходные данные: 32-битное беззнаковое целое число;
 | 
						||
 | 
						||
## Процесс коммуникации
 | 
						||
 | 
						||
1. mKCP разбивает поток данных на несколько пакетов для отправки. Каждый поток данных имеет уникальный идентификатор, который используется для различения разных потоков данных. Каждый пакет данных в потоке данных несет один и тот же идентификатор.
 | 
						||
2. У mKCP нет процесса рукопожатия. При получении пакета данных определяется, является ли это новым вызовом или текущим вызовом, на основе идентификатора потока данных, который он несет.
 | 
						||
3. Каждый пакет данных содержит несколько сегментов (Segment), которые делятся на три типа: данные (Data), подтверждение (ACK) и пульс (Ping). Каждый сегмент обрабатывается отдельно.
 | 
						||
 | 
						||
## Формат данных
 | 
						||
 | 
						||
### Пакет данных
 | 
						||
 | 
						||
| 4 байта                         | 2 байта        | L байт           |
 | 
						||
| ------------------------------- | -------------- | ---------------- |
 | 
						||
| Информация для аутентификации A | Длина данных L | Сегментная часть |
 | 
						||
 | 
						||
Где:
 | 
						||
 | 
						||
- Информация для аутентификации A = fnv(сегментная часть), big endian;
 | 
						||
- Сегментная часть может содержать несколько сегментов;
 | 
						||
 | 
						||
### Сегмент данных
 | 
						||
 | 
						||
| 2 байта            | 1 байт      | 1 байт    | 4 байта            | 4 байта             | 4 байта                               | 2 байта   | Len байт |
 | 
						||
| ------------------ | ----------- | --------- | ------------------ | ------------------- | ------------------------------------- | --------- | -------- |
 | 
						||
| Идентификатор Conv | Команда Cmd | Опция Opt | Временная метка Ts | Порядковый номер Sn | Неподтвержденный порядковый номер Una | Длина Len | Данные   |
 | 
						||
 | 
						||
Где:
 | 
						||
 | 
						||
- Идентификатор Conv: идентификатор потока данных mKCP
 | 
						||
- Команда Cmd: константа 0x01
 | 
						||
- Опция Opt: возможные значения:
 | 
						||
  - 0x00: пустая опция
 | 
						||
  - 0x01: другая сторона отправила все данные
 | 
						||
- Временная метка Ts: время отправки текущего сегмента с удаленной стороны, big endian
 | 
						||
- Порядковый номер Sn: позиция сегмента данных в потоке данных, порядковый номер начального сегмента равен 0, каждый последующий сегмент увеличивается на 1
 | 
						||
- Неподтвержденный порядковый номер Una: минимальный Sn, который отправляется удаленным хостом и еще не получил подтверждение
 | 
						||
 | 
						||
### Сегмент подтверждения
 | 
						||
 | 
						||
| 2 байта            | 1 байт      | 1 байт    | 4 байта  | 4 байта                                  | 4 байта            | 2 байта   | Len \* 4 байта                   |
 | 
						||
| ------------------ | ----------- | --------- | -------- | ---------------------------------------- | ------------------ | --------- | -------------------------------- |
 | 
						||
| Идентификатор Conv | Команда Cmd | Опция Opt | Окно Wnd | Следующий порядковый номер для приема Sn | Временная метка Ts | Длина Len | Подтвержденные порядковые номера |
 | 
						||
 | 
						||
Где:
 | 
						||
 | 
						||
- Идентификатор Conv: идентификатор потока данных mKCP
 | 
						||
- Команда Cmd: константа 0x00
 | 
						||
- Опция Opt: как указано выше
 | 
						||
- Окно Wnd: максимальный порядковый номер, который может принять удаленный хост
 | 
						||
- Следующий порядковый номер для приема Sn: минимальный порядковый номер сегмента данных, который не получил удаленный хост
 | 
						||
- Временная метка Ts: временная метка последнего полученного сегмента данных удаленным хостом, может использоваться для расчета задержки
 | 
						||
- Подтвержденные порядковые номера: каждые 4 байта указывают, что данные с этим порядковым номером получены и подтверждены
 | 
						||
 | 
						||
Комментарий:
 | 
						||
 | 
						||
- Удаленный хост ожидает получения данных с порядковыми номерами в диапазоне [Sn, Wnd)
 | 
						||
 | 
						||
### Сегмент пульса
 | 
						||
 | 
						||
| 2 байта            | 1 байт      | 1 байт    | 4 байта                               | 4 байта                                  | 4 байта      |
 | 
						||
| ------------------ | ----------- | --------- | ------------------------------------- | ---------------------------------------- | ------------ |
 | 
						||
| Идентификатор Conv | Команда Cmd | Опция Opt | Неподтвержденный порядковый номер Una | Следующий порядковый номер для приема Sn | Задержка Rto |
 | 
						||
 | 
						||
Где:
 | 
						||
 | 
						||
- Идентификатор Conv: идентификатор потока данных mKCP
 | 
						||
- Команда Cmd: возможные значения:
 | 
						||
  - 0x02: удаленный хост принудительно завершает сеанс
 | 
						||
  - 0x03: обычный пульс
 | 
						||
- Опция Opt: как указано выше
 | 
						||
- Неподтвержденный порядковый номер Una: тот же, что и Una в сегменте данных
 | 
						||
- Следующий порядковый номер для приема Sn: тот же, что и Sn в сегменте подтверждения
 | 
						||
- Задержка Rto: задержка, рассчитанная самим удаленным хостом
 |