# mKCP

mKCP использует UDP для имитации TCP-соединения.

mKCP жертвует пропускной способностью ради уменьшения задержки. При передаче одного и того же контента mKCP, как правило, потребляет больше трафика, чем TCP.

::: tip
Убедитесь, что на хосте правильно настроена конфигурация брандмауэра.
:::

## KcpObject

`KcpObject` соответствует параметрам передачи `kcpSettings`.

```json
{
  "mtu": 1350,
  "tti": 20,
  "uplinkCapacity": 5,
  "downlinkCapacity": 20,
  "congestion": false,
  "readBufferSize": 1,
  "writeBufferSize": 1,
  "header": {
    "type": "none",
    "domain": "example.com"
  },
  "seed": "Password"
}
```

> `mtu`: number

Максимальный размер передаваемого блока (maximum transmission unit).

Выберите значение от 576 до 1460.

По умолчанию `1350`.

> `tti`: number

Интервал передачи (transmission time interval), в миллисекундах (ms), mKCP будет отправлять данные с этой частотой.

Выберите значение от 10 до 100.

По умолчанию `50`.

> `uplinkCapacity`: number

Пропускная способность канала отправки, то есть максимальная полоса пропускания, используемая хостом для отправки данных, в МБ/с (обратите внимание это байты, а не биты).

Может быть установлено в 0, что означает очень маленькую пропускную способность.

По умолчанию `5`.

> `downlinkCapacity`: number

Пропускная способность канала приема, то есть максимальная полоса пропускания, используемая хостом для приема данных, в МБ/с (обратите внимание что это байты, а не биты).

Может быть установлено в 0, что означает очень маленькую пропускную способность.

По умолчанию `20`.

::: tip
`uplinkCapacity` и `downlinkCapacity` определяют скорость передачи mKCP.

В качестве примера, если клиент отправляет данные, то `uplinkCapacity` клиента определяет скорость отправки данных, а `downlinkCapacity` сервера определяет скорость приема данных. Значение, меньшее из двух, будет использоваться в качестве определяющего.

Рекомендуется установить `downlinkCapacity` в большое значение, например, 100, а `uplinkCapacity` - в фактическое значение скорости сети. Когда скорость недостаточна, можно постепенно увеличивать значение `uplinkCapacity` до примерно двух раз больше, чем фактическая скорость сети.
:::

> `congestion`: true | false

Включить или отключить контроль перегрузки.

При включении контроля перегрузки Xray будет автоматически отслеживать качество сети. При серьезных потерях пакетов он автоматически снизит пропускную способность; при хорошем качестве сети он также будет соответствующим образом увеличивать пропускную способность.

По умолчанию `false`.

> `readBufferSize`: number

Размер буфера чтения для отдельного соединения, в МБ.

По умолчанию `2`.

> `writeBufferSize`: number

Размер буфера записи для отдельного соединения, в МБ.

По умолчанию `2`.

::: tip
`readBufferSize` и `writeBufferSize` определяют размер памяти, используемой для каждого соединения.

При необходимости высокой скорости передачи, установка больших значений `readBufferSize` и `writeBufferSize` может в некоторой степени повысить скорость, но также будет использовать больше памяти.

При скорости сети не превышающей 20 МБ/с, значение по умолчанию 1 МБ может удовлетворить требованиям; при превышении этой скорости можно соответствующим образом увеличить значения `readBufferSize` и `writeBufferSize`, а затем вручную сбалансировать скорость и использование памяти.
:::

> `header`: [HeaderObject](#headerobject)

Настройка маскировки заголовка данных

> `seed`: string

Опциональное шифрование пароля, используемое для шифрования потока данных с помощью алгоритма AES-128-GCM. Клиент и сервер должны использовать одинаковый пароль.

Эта шифровальная схема не предназначена для обеспечения безопасности контента, но может помочь противостоять некоторым блокировкам.

> В настоящее время в тестовой среде, после включения этой настройки, не наблюдалось явления блокировки исходного, не зашифрованного варианта.

### HeaderObject

```json
{
  "type": "none",
  "domain": "example.com"
}
```

> `type`: string

Тип маскировки, доступные значения:

- `"none"`: значение по умолчанию, не применяется маскировка, отправляемые данные не имеют никаких отличительных признаков.
- `"srtp"`: маскировка под SRTP-пакеты, будет идентифицироваться как данные видеозвонка (например, FaceTime).
- `"utp"`: маскировка под uTP-пакеты, будет идентифицироваться как данные загрузки BT.
- `"wechat-video"`: маскировка под пакеты видеозвонка WeChat.
- `"dtls"`: маскировка под DTLS 1.2-пакеты.
- `"wireguard"`: маскировка под WireGuard-пакеты. (Это не настоящий протокол WireGuard).
- `"dns"`: некоторые корпоративные сети разрешают DNS-запросы без авторизации, добавление DNS-заголовка к KCP-пакетам позволяет обойти некоторые корпоративные сети.

> `domain`: string

Используется совместно с типом маскировки `"dns"`, можно указать произвольный домен.

## Благодарности

- [@skywind3000](https://github.com/skywind3000) изобрел и реализовал протокол KCP.
- [@xtaci](https://github.com/xtaci) перевел реализацию KCP с C на Go.
- [@xiaokangwang](https://github.com/xiaokangwang) протестировал интеграцию KCP с Xray и внес первый PR.

## Улучшения протокола KCP

### Более компактный заголовок протокола

Протокол KCP использует заголовок размером 24 байта, а mKCP уменьшил его до 18 байт для пакета данных и 16 байт для пакета подтверждения. Более компактный заголовок помогает избежать обнаружения по признакам и ускоряет передачу данных.

Кроме того, в оригинальном KCP каждый пакет подтверждения может подтвердить только один пакет данных, то есть, если KCP нужно подтвердить получение 100 пакетов данных, он отправит 24 _ 100 = 2400 байт данных. В этом случае многократно повторяются заголовки, что приводит к ненужному расходу полосы пропускания. mKCP сжимает несколько пакетов подтверждения, 100 пакетов подтверждения занимают всего 16 + 2 + 100 _ 4 = 418 байт, что в шесть раз меньше, чем в оригинальном KCP.

### Передача пакетов подтверждения

В оригинальном KCP пакет подтверждения отправляется только один раз, если пакет подтверждения потерян, то обязательно произойдет повторная передача данных, что приводит к ненужному расходу полосы пропускания. mKCP будет повторно отправлять пакеты подтверждения с определенной частотой, пока отправитель не получит подтверждение. Размер одного пакета подтверждения составляет 22 байта, что значительно меньше, чем размер пакета данных, который составляет более 1000 байт, поэтому повторная передача пакета подтверждения имеет гораздо меньшую цену.

### Управление состоянием соединения

mKCP может эффективно управлять состоянием соединения. Когда удаленный хост инициализирует закрытие соединения, соединение будет закрыто в течение двух секунд; когда удаленный хост теряет соединение, соединение будет закрыто в течение максимум 30 секунд.

Оригинальный KCP не поддерживает этот сценарий.
