README em inglês
KCP é um protocolo rápido e confiável que pode reduzir o atraso médio em 30% a 40% e reduzir o atraso máximo em três vezes ao custo de 10% a 20% mais largura de banda que o TCP. A implementação pura do algoritmo não é responsável pelo envio e recebimento de protocolos subjacentes (como UDP). Os usuários precisam definir o método de envio dos pacotes de dados da camada inferior e fornecê-los ao KCP na forma de retorno de chamada. Até o relógio precisa ser transmitido externamente e não haverá nenhuma chamada de sistema internamente.
Todo o protocolo possui apenas dois arquivos de origem, ikcp.h e ikcp.c, que podem ser facilmente integrados à pilha de protocolos do próprio usuário. Talvez você tenha implementado um protocolo P2P ou baseado em UDP, mas não possui uma implementação completa e confiável do protocolo ARQ. Em seguida, basta copiar esses dois arquivos para o projeto existente, escrever algumas linhas de código e você poderá usá-lo.
O TCP foi projetado para tráfego (quantos KB de dados podem ser transmitidos por segundo) e a ênfase está no uso total da largura de banda. O KCP foi projetado para taxa de fluxo (quanto tempo leva para um único pacote de dados ser enviado de uma extremidade a outra). Ele troca 10% a 20% do desperdício de largura de banda por uma velocidade de transmissão 30% a 40% mais rápida que o TCP). . O canal TCP é um canal grande com uma vazão lenta, mas uma grande vazão por segundo, enquanto o canal KCP é um canal pequeno e rápido com fluxo rápido. O KCP possui dois tipos: modo normal e modo rápido. O resultado do aumento da vazão é alcançado através das seguintes estratégias:
O cálculo do tempo limite do TCP é RTOx2. Se você perder três pacotes consecutivos, ele se tornará RTOx8, o que é muito assustador, mas depois que o KCP inicia o modo rápido, não é x2, mas apenas x1,5 (experimentos provaram isso). o valor de 1,5 é relativamente bom), o que melhora a velocidade de transmissão.
Quando o TCP perde um pacote, ele retransmite todos os dados a partir do pacote perdido. O KCP retransmite seletivamente e retransmite apenas os pacotes de dados verdadeiramente perdidos.
O remetente enviou vários pacotes 1, 2, 3, 4 e 5 e depois recebeu o ACK da extremidade remota: 1, 3, 4, 5. Ao receber ACK3, o KCP sabia que 2 foi ignorado uma vez e recebeu quando ACK4 é recebido, sabe-se que o pacote 2 foi ignorado duas vezes. Neste momento, pode-se considerar que o pacote número 2 foi perdido. Não há necessidade de esperar o tempo limite e o pacote número 2 pode ser retransmitido diretamente, o que melhora muito. a velocidade de transmissão quando os pacotes são perdidos.
Para aproveitar ao máximo a largura de banda, o TCP atrasa o envio de ACK (NODELAY é inútil). Desta forma, o cálculo do tempo limite calculará um tempo RTT maior, o que prolonga o processo de julgamento quando ocorre perda de pacotes. O envio atrasado do ACK do KCP pode ser ajustado.
Existem dois tipos de respostas do modelo ARQ, UNA (todos os pacotes anteriores a este número foram recebidos, como TCP) e ACK (pacotes com este número foram recebidos). Usar apenas UNA causará todas as retransmissões, enquanto usar apenas ACK causará). um custo de perda muito alto No passado, os protocolos consistiam em escolher um dos dois, mas no protocolo KCP, exceto para pacotes ACK individuais, todos os pacotes possuem informações UNA.
O modo normal do KCP usa a mesma regra de concessão justa do TCP, ou seja, o tamanho da janela de envio é determinado por quatro fatores: o tamanho do buffer de envio, o tamanho restante do buffer de recebimento na extremidade receptora, a concessão de perda de pacotes e o início lento. No entanto, ao transmitir pequenos dados com altos requisitos de pontualidade, você pode optar por pular as duas últimas etapas da configuração e usar apenas os dois primeiros itens para controlar a frequência de envio. À custa da justiça parcial e da utilização da largura de banda, o efeito de transmissão suave pode ser alcançado mesmo quando o BT está ligado.
Você pode baixar e instalar o kcp usando o gerenciador de biblioteca vcpkg:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install kcp
A biblioteca kcp no vcpkg é mantida atualizada pelos membros da equipe da Microsoft e pelos colaboradores da comunidade. Se a versão estiver desatualizada, crie um problema ou levante um PR no repositório vcpkg.
Criar objeto KCP:
// 初始化 kcp对象,conv为一个表示会话编号的整数,和tcp的 conv一样,通信双
// 方需保证 conv相同,相互的数据包才能够被认可,user是一个给回调函数的指针
ikcpcb *kcp = ikcp_create(conv, user);
Definir função de retorno de chamada:
// KCP的下层协议输出函数,KCP需要发送数据时会调用它
// buf/len 表示缓存和长度
// user指针为 kcp对象创建时传入的值,用于区别多个 KCP对象
int udp_output ( const char *buf, int len, ikcpcb *kcp, void *user)
{
....
}
// 设置回调函数
kcp->output = udp_output;
Chamada de atualização em loop:
// 以一定频率调用 ikcp_update来更新 kcp状态,并且传入当前时钟(毫秒单位)
// 如 10ms调用一次,或用 ikcp_check确定下次调用 update的时间不必每次调用
ikcp_update (kcp, millisec);
Insira um pacote de camada inferior:
// 收到一个下层数据包(比如UDP包)时需要调用:
ikcp_input (kcp, received_udp_packet, received_udp_size);
Após processar a saída/entrada do protocolo da camada inferior, o protocolo KCP pode funcionar normalmente. Use ikcp_send para enviar dados para a extremidade remota. A outra extremidade usa ikcp_recv(kcp, ptr, size) para receber dados.
O modo padrão do protocolo é um ARQ padrão e vários interruptores de aceleração precisam ser ativados por meio da configuração:
Modo de trabalho:
int ikcp_nodelay (ikcpcb *kcp, int nodelay, int interval, int resend, int nc)
Janela máxima:
int ikcp_wndsize (ikcpcb *kcp, int sndwnd, int rcvwnd);
Esta chamada definirá a janela máxima de envio e o tamanho máximo da janela de recebimento do protocolo, cujo padrão é 32. Isso pode ser entendido como SND_BUF e RCV_BUF do TCP, mas as unidades são diferentes. A unidade SND/RCV_BUF é bytes, e esta unidade é. pacotes.
Unidade máxima de transmissão:
O protocolo de algoritmo puro não é responsável por detectar o MTU. O mtu padrão é 1400 bytes. Você pode usar ikcp_setmtu para definir esse valor. Este valor afetará a unidade máxima de transmissão ao combinar e fragmentar pacotes de dados.
RTO mínimo:
Quer seja TCP ou KCP, há um limite mínimo de RTO ao calcular o RTO. Mesmo que o RTO calculado seja de 40 ms, como o RTO padrão é de 100 ms, o protocolo só pode detectar perda de pacotes após 100 ms. Este valor pode ser alterado manualmente:
kcp->rx_minrto = 10 ;
O uso e a configuração do protocolo são muito simples. Na maioria dos casos, você pode basicamente utilizá-lo após ler o conteúdo acima. Se você precisar de um controle mais refinado, como alterar o alocador de memória do KCP, ou precisar agendar conexões KCP com mais eficiência em grande escala (como mais de 3.500), ou como integrar melhor com o TCP, então você pode continue lendo:
Leitura relacionada: “Genshin Impact” também está usando KCP para acelerar notícias de jogos
O KCP foi executado com sucesso em vários projetos com centenas de milhões de usuários, proporcionando-lhes uma experiência de rede mais ágil e fluida.
Bem-vindo para nos contar mais casos
Se a rede nunca travar, o KCP/TCP se comportará de maneira semelhante, mas a rede em si não é confiável e a perda de pacotes e o jitter são inevitáveis (caso contrário, por que precisaríamos de vários protocolos confiáveis)? Quando comparados diretamente em um ambiente quase ideal como a intranet, todos são quase iguais. No entanto, quando colocados na rede pública, colocados em uma rede 3G/4G ou usando simulação de perda de pacotes na intranet, a lacuna torna-se óbvia. A rede pública tem uma perda média de pacotes de cerca de 10% durante os períodos de pico, e é ainda pior em WiFi/3g/4g, o que causará atrasos na transmissão.
Agradecimentos a Zhangyuan, autor do asio-kcp, pela avaliação horizontal do KCP, enet e udt. As conclusões são as seguintes:
Para obter detalhes, consulte: Comparação horizontal e dados de avaliação fornecem mais orientação para aqueles que estão hesitantes em escolher.
O enorme mecanismo de servidor de jogos multijogador SpatialOS fez a mesma avaliação que o TCP/RakNet após integrar o protocolo KCP:
Comparamos o tempo de resposta ao manter 50 caracteres ao mesmo tempo com uma taxa de atualização de 60 Hz no lado do servidor. Consulte o relatório de comparação detalhado:
Nos últimos anos, os jogos online e diversas redes sociais cresceram exponencialmente. Independentemente dos jogos online ou das diversas redes sociais interativas, a interatividade e a complexidade estão aumentando rapidamente, e todos eles precisam entregar dados simultaneamente em um tempo muito curto. dos usuários, a tecnologia de transmissão se tornará naturalmente um fator importante que restringe o desenvolvimento futuro, e vários protocolos de transmissão bem conhecidos no mundo de código aberto, como raknet/enet Por exemplo, quando um lançamento é feito, toda a pilha de protocolos é lançada em conjunto. Este formulário não é propício à diversificação. Meu projeto só pode escolher usar você ou não. um conjunto de pilhas de protocolos, por melhor que seja, é muito difícil atender a várias necessidades de diferentes ângulos.
Portanto, o método do KCP é "desmontar" a pilha de protocolos para que todos possam ajustá-la e montá-la com flexibilidade de acordo com as necessidades do projeto. Você pode adicionar uma camada de código de eliminação de Reed Solomon abaixo para FEC e uma camada acima para RC4/Salsa20. Para criptografia de fluxo, uma troca assimétrica de chaves é projetada no handshake e um sistema de roteamento dinâmico é construído na camada de transporte UDP subjacente para detectar vários caminhos ao mesmo tempo e selecionar o melhor caminho para transmissão. Essas diferentes "unidades de protocolo" podem ser combinadas livremente conforme necessário, como blocos de construção, para garantir "simplicidade" e "destacabilidade", para que possam se adaptar com flexibilidade às mudanças nas necessidades do negócio. Se algum módulo não for bom, basta substituí-lo.
As futuras soluções de transmissão devem ser profundamente personalizadas de acordo com os cenários de uso, por isso oferecemos a todos uma "unidade de protocolo" que pode ser combinada livremente para facilitar a integração em sua própria pilha de protocolos.
Para mais informações, consulte as Histórias de Sucesso.
Autor: Lin Wei (skywind3000)
Bem-vindo a me seguir em: blog pessoal e Twitter.
Em meus muitos anos de experiência em desenvolvimento, sempre gostei de estudar e resolver alguns problemas de gargalo em programas. Nos meus primeiros anos, gostava de desenvolvimento de jogos, segui "Programação VGA" para fazer gráficos de jogos e li o "Programa Gráfico" de Michael Abrash. Guia do desenvolvedor" para fazer renderização suave. Gosto de brincar com alguns códigos que podem comprimir a CPU e rodar mais rápido. Depois de ingressar no trabalho, meu interesse mudou para tecnologias relacionadas ao servidor e à rede.
Em 2007, depois de fazer vários jogos tradicionais, comecei a estudar o problema de sincronização de jogos de ação rápida. Durante esse período, escrevi muitos artigos e fui uma das primeiras pessoas na China a estudar problemas de sincronização. não importa como resolver a sincronização, precisamos fazer algo em termos de transmissão de rede. Depois de sair do jogo e mudar para a Internet, também descobri que muitos campos têm essa necessidade, então comecei a me dedicar à área de transmissão de rede. , tentando implementar alguns protocolos conservadores e confiáveis baseados em UDP e imitando o código do BSD Lite 4.4 para implementar alguns protocolos semelhantes ao TCP protocolo, achei bastante interessante e depois implementei alguns brinquedos relacionados a redes P2P e roteamento dinâmico. O protocolo KCP nasceu em 2011. É basicamente um dos vários brinquedos feitos por ele mesmo em termos de transmissão.
O autor de Kcptun, xtaci, é meu colega de faculdade. Ambos nos especializamos em comunicação e frequentemente estudamos juntos como otimizar a transmissão.
Bem-vindo ao usar o Alipay para escanear o código QR acima para doar para este projeto. As doações serão usadas para otimizar continuamente o protocolo KCP e melhorar a documentação.
Agradecimentos a: Mingming, Xingzi, Jin, Fan, Yanzhao, Binquan, Xiaodan, Yu Zheng, Hu, Shenggan, Xu Wei, Wang Chuan, Zhao Gangqiang, Hu Zhifeng, Wan Xinchao, He Xinchao, Liu Yang, Hou Xianhui, Wu Peiyi , Hua Bin, Rutão, Hu Jian. . . (Lamento não ter registrado a lista anterior) Estamos aguardando as doações e apoio de nossos colegas.
Bem-vindo a prestar atenção
Grupo de comunicação KCP: 364933586 (número do grupo QQ), integração KCP, ajuste, transmissão de rede e discussões técnicas relacionadas
Grupo Gitter: https://gitter.im/skywind3000/KCP
blog: http://www.skywind.me
Este projeto existe graças a todas as pessoas que contribuem.