Clique aqui para versão em inglês
Qualquer pessoa que tenha usado banda larga doméstica das três principais operadoras e precise de interconexão de banda larga doméstica quase sempre experimentará a velocidade limitada do UDP. Para evitar a QoS das três principais operadoras de UDP, fiz outra ferramenta chamada UDP Hop. O princípio é estabelecer regularmente novas conexões (alterar números de porta e conectar-se a novos endereços).
No entanto, o UDP Hop suporta apenas o encaminhamento de tráfego UDP. Para poder usar o UDP para encaminhar o tráfego TCP, existe o KCP Tube. A retransmissão confiável do KCP é usada para garantir que os pacotes TCP encaminhados não serão perdidos.
Outra razão para criar o KCP Tube é que outras ferramentas de encaminhamento KCP só podem encaminhar tráfego TCP, mas preciso usar o KCP para encaminhar o tráfego UDP. Principalmente pela comodidade de jogar.
É claro que o udphop e o kcptube foram concebidos ao mesmo tempo. Portanto, por uma questão de conveniência, primeiro configuramos o tubo KCP e configuramos a estrutura e, em seguida, cortamos em UDP Hop com base no tubo KCP. Em seguida, faça a mesclagem reversa do código de patch UDP Hop de volta ao KCP Tube.
Para facilitar os usuários domésticos de banda larga Full Cone NAT, o KCP Tube pode usar STUN para fazer furos ao executar no modo de servidor básico e suporta IPv4 e IPv6.
Assim como o propósito do próprio KCP, o principal objetivo do KCP Tube é reduzir a latência, ao invés de favorecer a transmissão de tráfego extremamente grande. Então, ele pode transmitir tráfego extremamente grande? Sim, mas o efeito pode não ser tão bom quanto a ferramenta de encaminhamento TCP-KCP existente.
Atualmente 3 modos são suportados:
Observe que a hora do cliente e a hora do servidor devem estar sincronizadas e a diferença horária não pode ser superior a 255 segundos.
Por favor, vá para a página wiki ou para a página de documentação.
Se você precisar de um gerador de perfil, clique aqui: KCPTube Generator
kcptube config.conf
Exemplo de modo cliente:
mode=client
kcp=regular3
inbound_bandwidth=500M
outbound_bandwidth=50M
listen_port=59000
destination_port=3000
destination_address=123.45.67.89
encryption_password=qwerty1234
encryption_algorithm=AES-GCM
Exemplo de modo servidor:
mode=server
kcp=regular3
inbound_bandwidth=1G
outbound_bandwidth=1G
listen_port=3000
destination_port=59000
destination_address=::1
encryption_password=qwerty1234
encryption_algorithm=AES-GCM
stun_server=stun.qq.com
log_path=./
Nota: Ao conectar-se pela primeira vez, o servidor informará ao cliente seu intervalo de portas, portanto, listen_port
no modo cliente não precisa necessariamente ser igual destination_port
no modo servidor. As portas em ambos os lados podem ser inconsistentes, mas. o intervalo de números de porta gravado pelo cliente não pode ir além do escopo do servidor para evitar que o cliente selecione a porta errada e não consiga se conectar.
Se você deseja especificar a placa de rede de escuta, especifique o endereço IP da placa de rede e adicione uma linha.
listen_on=192.168.1.1
Se você quiser escutar múltiplas portas e múltiplas placas de rede, separe vários arquivos de configuração.
kcptube config1.conf config2.conf
Se quiser testar se a conexão está tranquila antes de conectar, você pode adicionar a opção --try
kcptube --try config1.conf
ou
kcptube config1.conf --try
Use a opção --check-config
para verificar se o arquivo de configuração está correto:
kcptube --check-config config1.conf
ou
kcptube config1.conf --check-config
Exemplo de modo cliente:
mode=client
kcp=regular3
inbound_bandwidth=500M
outbound_bandwidth=50M
listen_port=6000
destination_port=3000-4000
destination_address=123.45.67.89
dport_refresh=600
encryption_password=qwerty1234
encryption_algorithm=AES-GCM
Exemplo de modo servidor:
mode=server
kcp=regular3
inbound_bandwidth=1G
outbound_bandwidth=1G
listen_port=3000-4000
destination_port=6000
destination_address=::1
encryption_password=qwerty1234
encryption_algorithm=AES-GCM
Exemplo de modo cliente:
mode=client
kcp=manual
kcp_mtu=1400
kcp_sndwnd=512
kcp_rcvwnd=2048
kcp_nodelay=1
kcp_interval=10
kcp_resend=2
kcp_nc=true
udp_timeout=300
listen_port=6000
destination_port=3000-4000
destination_address=123.45.67.89
dport_refresh=600
encryption_password=qwerty1234
encryption_algorithm=AES-GCM
Exemplo de modo servidor:
mode=server
kcp=manual
kcp_mtu=1400
kcp_sndwnd=512
kcp_rcvwnd=2048
kcp_nodelay=1
kcp_interval=10
kcp_resend=2
kcp_nc=true
udp_timeout=300
listen_port=3000-4000
destination_port=6000
destination_address=::1
encryption_password=qwerty1234
encryption_algorithm=AES-GCM
nome | Valor configurável | Obrigatório | Observação |
---|---|---|---|
modo | cliente servidor relé | sim | Nó de retransmissão cliente-servidor |
ouvir_on | Nome de domínio ou endereço IP | não | Apenas o nome de domínio ou endereço IP pode ser preenchido. Separe vários endereços com vírgulas |
porta_escuta | 1-65535 | sim | Ao executar como servidor, você pode especificar um intervalo de portas |
porta_destino | 1-65535 | sim | Os intervalos de portas podem ser especificados durante a execução como cliente. Separe vários endereços com vírgulas |
endereço_destino | Endereço IP, nome de domínio | sim | Não são necessários colchetes ao preencher o endereço IPv6 |
dport_refresh | 0 - 32767 | não | A unidade é "segundo". Se deixado em branco, será utilizado o valor padrão de 60 segundos. 1 a 20 é calculado como 20 segundos e maior que 32.767 é calculado como 32.767 segundos. Defina como 0 para desativar. |
algoritmo_de criptografia | AES-GCM AES-OCB chacha20 xchacha20 nenhum | não | AES-256-GCM-AEAD AES-256-OCB-AEAD ChaCha20-Poly1305 XChaCha20-Poly1305 Sem criptografia |
criptografia_senha | qualquer personagem | Depende da situação | Obrigatório quando o algoritmo de criptografia está definido e não é nenhum |
udp_timeout | 0 - 65535 | não | A unidade é "segundo". O valor padrão é 180 segundos. Se definido como 0, o valor padrão será usado. Esta opção representa a configuração de tempo limite entre o aplicativo UDP ↔ kcptube. |
keep_alive | 0 - 65535 | não | A unidade é "segundo". O valor padrão é 0, o que equivale a desabilitar Keep Alive. Esta opção refere-se a Keep Alive entre duas extremidades do KCP Pode ser habilitado unilateralmente para detectar se o canal para de responder. Se não houver resposta após 30 segundos, o canal será fechado. |
mux_tunnels | 0 - 65535 | não | O valor padrão é 0, o que equivale a não utilizar canais de multiplexação. Esta opção refere-se ao número de canais de multiplexação entre as duas extremidades do KCP. Esta opção só está habilitada no lado do cliente. |
servidor_stun | Endereço do servidor STUN | não | Não pode ser usado quando listen_port está no modo de intervalo de portas |
log_path | Diretório para armazenar Log | não | Não é possível apontar para o próprio arquivo |
fec | uint8:uint8 | não | O formato é fec=D:R , por exemplo, fec=20:3 pode ser preenchido.Nota: O valor total máximo de D + R é 255 e não pode exceder este número. Um valor 0 em cada lado dos dois pontos indica que a opção não é usada. As configurações devem ser iguais em ambas as extremidades. Para obter detalhes, consulte o guia de uso do FEC. |
mtu | número inteiro positivo | não | Valor atual de MTU da rede, usado para calcular automaticamente kcp_mtu |
kcp_mtu | número inteiro positivo | não | O valor padrão é 1440. O valor definido ao chamar ikcp_setmtu() é o comprimento do conteúdo dos dados no pacote UDP. |
kcp | manual rápido1-6 normal1-5 | sim | Definir manualmente a velocidade normal rápida (Número no final: quanto menor o número, mais rápida será a velocidade) |
kcp_sndwnd | número inteiro positivo | não | Os valores padrão são mostrados na tabela abaixo e podem ser substituídos individualmente. |
kcp_rcvwnd | número inteiro positivo | não | Os valores padrão são mostrados na tabela abaixo e podem ser substituídos individualmente. |
kcp_nodelay | número inteiro positivo | Depende da situação | Obrigatório quando kcp=manual, o valor padrão é mostrado na tabela abaixo |
kcp_interval | número inteiro positivo | Depende da situação | Obrigatório quando kcp=manual, o valor padrão é mostrado na tabela abaixo |
kcp_resend | número inteiro positivo | Depende da situação | Obrigatório quando kcp=manual, o valor padrão é mostrado na tabela abaixo |
kcp_nc | sim verdadeiro 1 não falso 0 | Depende da situação | Obrigatório quando kcp=manual, o valor padrão é mostrado na tabela abaixo |
largura de banda de saída | número inteiro positivo | não | Largura de banda de saída, usada para atualizar dinamicamente o valor de kcp_sndwnd durante o processo de comunicação |
largura de banda_de entrada | número inteiro positivo | não | Largura de banda de entrada, usada para atualizar dinamicamente o valor de kcp_rcvwnd durante o processo de comunicação |
ipv4_only | sim verdadeiro 1 não falso 0 | não | Se o IPv6 estiver desabilitado no sistema, esta opção deverá ser habilitada e definida como sim ou verdadeiro ou 1 |
ipv6_only | sim verdadeiro 1 não falso 0 | não | Ignorar endereços IPv4 |
explosão | sim verdadeiro 1 não falso 0 | não | Tente ignorar as configurações de controle de fluxo KCP e encaminhe os pacotes o mais rápido possível. Pode causar carga excessiva |
[ouvinte] | N / D | sim (apenas modo de relé) | O rótulo do modo relé, usado para especificar o KCP no modo de escuta. A configuração deste rótulo indica os dados de interação com o cliente. |
[transitário] | N / D | sim (apenas modo de relé) | O rótulo do modo de retransmissão, usado para especificar o KCP do modo de transferência. A configuração deste rótulo indica os dados de interação com o servidor. |
[entrada_personalizada] | N / D | não | Etiqueta do modo de mapeamento personalizado. Para uso, consulte Como usar o mapeamento personalizado. |
[custom_input_tcp] | N / D | não | Etiqueta do modo de mapeamento personalizado. Para uso, consulte Como usar o mapeamento personalizado. |
[custom_input_udp] | N / D | não | Etiqueta do modo de mapeamento personalizado. Para uso, consulte Como usar o mapeamento personalizado. |
Entre eles, encryption_algorithm
e encryption_password
devem ser consistentes em ambas as extremidades da comunicação.
nome | Valor configurável | Obrigatório | Observação |
---|---|---|---|
fib_ingress | 0 - 65535 | não | FIB usado por conexões de entrada |
fib_egress | 0 - 65535 | não | FIB usado para conexões de saída |
Sufixos disponíveis: K/M/G
O sufixo diferencia maiúsculas de minúsculas, maiúsculas são calculadas como binárias (1024) e minúsculas são calculadas como decimais (1000).
Preencha 1000, indicando que a largura de banda é 1000 bps
Preencha 100k, indicando que a largura de banda é de 100 kbps (100.000 bps)
Preencha 100K, indicando que a largura de banda é de 100 Kbps (102.400 bps)
Preencha 100M, indicando que a largura de banda é de 100 Mbps (102.400 Kbps)
Preencha 1G, indicando que a largura de banda é de 1 Gbps (1024 Mbps)
Observe que é bps (Bits por segundo), não Bps (Bytes por segundo).
Vale lembrar que o valor da largura de banda preenchido não deve ultrapassar a largura de banda real para evitar congestionamento na janela de envio.
NOTA IMPORTANTE :
O KCPTube calculará e definirá o tamanho da janela de envio do KCP cerca de 5 segundos após o link KCP ser estabelecido, com base no valor de atraso do pacote de handshake e nos valores de outbound_bandwidth e inbound_bandwidth. Dentro de um período de tempo após a conclusão da configuração, há uma grande chance de que o tráfego flutue significativamente ou até mesmo o tráfego caia repentinamente para 0 e levará vários segundos para se recuperar.
Modo rápido | kcp_sndwnd | kcp_rcvwnd | kcp_nodelay | kcp_interval | kcp_resend | kcp_nc |
---|---|---|---|---|---|---|
rápido1 | 2048 | 2048 | 1 | 1 | 2 | 1 |
rápido2 | 2048 | 2048 | 2 | 1 | 2 | 1 |
rápido3 | 2048 | 2048 | 1 | 1 | 3 | 1 |
rápido4 | 2048 | 2048 | 2 | 1 | 3 | 1 |
rápido5 | 2048 | 2048 | 1 | 1 | 4 | 1 |
rápido6 | 2048 | 2048 | 2 | 1 | 4 | 1 |
Modo de velocidade normal | kcp_sndwnd | kcp_rcvwnd | kcp_nodelay | kcp_interval | kcp_resend | kcp_nc |
---|---|---|---|---|---|---|
normal1 | 1024 | 1024 | 1 | 1 | 5 | 1 |
normal2 | 1024 | 1024 | 2 | 1 | 5 | 1 |
normal3 | 1024 | 1024 | 0 | 1 | 2 | 1 |
regular4 | 1024 | 1024 | 0 | 15 | 2 | 1 |
regular5 | 1024 | 1024 | 0 | 30 | 2 | 1 |
Entre eles, quanto maior a taxa de perda de pacotes (superior a 10%), maior a vantagem que kcp_nodelay=1 tem sobre kcp_nodelay=2. Quando a taxa de perda de pacotes não é particularmente alta, kcp_nodelay=2 pode tornar o atraso de atraso mais suave.
Para ambientes com baixa perda de pacotes, cada modo é adequado para uso. A única diferença reside no uso de mais ou menos tráfego desperdiçado, e o limite superior da velocidade máxima é diferente. Entre eles, o regular3 não desperdiça tanto tráfego.
Recomenda-se ativar blast=1
ao mesmo tempo.
Para ambientes com alta perda de pacotes, considere sobrepor a configuração FEC. Para obter detalhes, consulte o guia de uso do FEC.
Para obter mais detalhes, consulte a lista de parâmetros.
Depois que o endereço IP e a porta perfurados forem obtidos pela primeira vez, e após a alteração do endereço IP e da porta perfurados, o arquivo ip_address.txt será criado no diretório Log (sobrescrito se existir), e o IP endereço e porta serão escritos nele.
O endereço de perfuração obtido será exibido no console ao mesmo tempo.
log_path=
deve apontar para um diretório, não para o arquivo em si.
Se você não precisar gravar no arquivo de log, exclua a linha log_path
.
Servidores STUN comuns encontrados em NatTypeTeste:
Servidor STUN encontrado no Natter:
Outros servidores STUN: public-stun-list.txt
Para facilidade de uso, foram fornecidos arquivos binários executáveis para múltiplas plataformas:
Os binários pré-compilados são todos compilados estaticamente. A versão Linux é basicamente compilada estaticamente, exceto libc, então duas versões são preparadas, uma para glibc (2.31) e outra para musl.
Para o ambiente Linux, imagens Docker também são fornecidas (atualmente apenas x64). Baixe kcptube_docker_image.zip e descompacte-o e, em seguida, use docker load -i kcptube_docker.tar
para importá-lo.
Após a importação, o método de uso é:
docker run -v /path/to/config_file.conf:/config_file.conf kcptube config_file.conf
Por exemplo:
docker run -v /home/someone/config1.conf:/config1.conf kcptube config1.conf
Os usuários do FreeBSD podem copiar o arquivo binário baixado para /usr/local/bin/
e então executar o comando
chmod +x /usr/local/bin/kcptube
Os arquivos de serviço correspondentes foram preparados no diretório service
deste projeto.
/usr/local/etc/rc.d/
chmod +x /usr/local/etc/rc.d/kcptube
/usr/local/etc/kcptube/
config.conf
/usr/local/etc/kcptube/config.conf
kcptube_enable="YES"
ao /etc/rc.conf
Finalmente, execute service kcptube start
para iniciar o serviço
O compilador deve suportar C++20
Bibliotecas dependentes:
Por favor, use vcpkg para instalar os pacotes de dependência asio
e botan
com antecedência. O comando é o seguinte:
vcpkg install asio:x64-windows asio:x64-windows-static
vcpkg install botan:x64-windows botan:x64-windows-static
(Se você precisar da versão ARM ou x86 de 32 bits, ajuste você mesmo as opções)
Em seguida, use o Visual Studio para abrir slnkcptube.sln
e compile você mesmo
Da mesma forma, instale primeiro as dependências asio e botan3. Além disso, cmake é necessário para instalá-lo com o próprio pacote do sistema:
pkg install asio botan3 cmake
Em seguida, construa no diretório build
mkdir build
cd build
cmake ..
make
As etapas são semelhantes ao FreeBSD. Para NetBSD, use pkgin para instalar dependências e cmake:
pkgin install asio
pkgin install cmake
OpenBSD Por favor, use pkg_add
para instalar as duas dependências acima. DragonflyBSD, por favor, use pkg
, o uso é o mesmo do FreeBSD.
Como o botan-3 não foi incluído nesses sistemas BSD, você mesmo deve compilar o botan-3.
Para as etapas restantes de construção, consulte o FreeBSD acima.
Observe que como esses BSDs vêm com versões inferiores do compilador, instale uma versão superior do GCC com antecedência.
Os passos são semelhantes ao FreeBSD. Por favor, use o gerenciador de pacotes que vem com a distribuição para instalar o asio, botan3 e cmake.
apk add asio botan3-libs cmake
Em seguida, construa no diretório build
mkdir build
cd build
cmake ..
make
Existem duas maneiras
Prática 1
Compile de acordo com o processo normal, exclua o arquivo binário kcptube recém-gerado e execute o comando
make VERBOSE=1
Em seguida, extraia o último comando de link C++ do conteúdo de saída e altere -lbotan-3
no meio para o caminho completo de libbotan-3.a, como /usr/lib/x86_64-linux-gnu/libbotan-3.a
.
Prática 2
Abra src/CMakeLists.txt e altere target_link_libraries(${PROJECT_NAME} PRIVATE botan-3)
para target_link_libraries(${PROJECT_NAME} PRIVATE botan-3 -static)
Então ele compila normalmente. Observe que se o sistema usar glibc, ele será compilado estaticamente junto com glibc e um aviso sobre getaddrinfo aparecerá.
Não tenho um computador Apple, então resolva todas as etapas sozinho.
Aumentar o cache de recebimento pode melhorar o desempenho da transmissão UDP
Você pode usar o comando sysctl kern.ipc.maxsockbuf
para visualizar o tamanho do cache. Caso sejam necessários ajustes, execute o comando (altere o número para o valor desejado):
sysctl -w kern.ipc.maxsockbuf=33554434
Ou escreva em /etc/sysctl.conf
kern.ipc.maxsockbuf=33554434
Você pode usar o comando sysctl net.inet.udp.recvspace
para verificar o tamanho do buffer de recebimento. Caso sejam necessários ajustes, execute o comando (altere o número para o valor desejado):
sysctl -w net.inet.udp.recvspace=33554434
Ou escreva em /etc/sysctl.conf
net.inet.udp.recvspace=33554434
Se necessário, você pode ajustar o valor de net.inet.udp.sendspace
ao mesmo tempo. Esta é a configuração do cache de envio.
Para o cache de recebimento, você pode usar os comandos sysctl net.core.rmem_max
e sysctl net.core.rmem_default
para visualizar o tamanho do cache de recebimento.
Caso sejam necessários ajustes, execute o comando (altere o número para o valor desejado):
sysctl -w net.core.rmem_max=33554434
sysctl -w net.core.rmem_default=33554434
Ou escreva em /etc/sysctl.conf
net.core.rmem_max=33554434
net.core.rmem_default=33554434
Se necessário, você pode ajustar os valores de net.core.wmem_max
e net.core.wmem_default
ao mesmo tempo. Esta é a configuração do cache de envio.
Como o kcptube usa internamente pilha única IPv6 + ativa o endereço mapeado IPv4 (IPv6 mapeado para IPv4) para usar redes IPv4 e IPv6, certifique-se de que o valor da opção v6only seja 0.
Em circunstâncias normais, nenhuma configuração adicional é necessária. FreeBSD, Linux e Windows permitem que endereços IPv4 sejam mapeados para IPv6 por padrão.
Se o sistema não suportar IPv6 ou se o IPv6 estiver desabilitado, defina ipv4_only=true no arquivo de configuração, para que o kcptube volte a usar o modo de pilha única IPv4.
Usar comando
sysctl -w net.inet6.ip6.v6only=0
Após a configuração, o modo de pilha única + endereço mapeado pode ouvir pilha dupla.
No entanto, devido a razões desconhecidas, o endereço mapeado IPv4 pode não estar conectado ativamente.
Como o OpenBSD bloqueia completamente os endereços de mapeamento IPv4, se você usar pilha dupla na plataforma OpenBSD, será necessário salvar dois arquivos de configuração, um dos quais habilita ipv4_only=1, e então carregar os dois arquivos de configuração ao mesmo tempo ao usar o kcptube.
Na maioria dos casos, esse prompt será encontrado apenas no lado do servidor, não no lado do cliente.
Se for realmente encontrado no cliente, verifique se o valor de mux_tunnels
é muito alto (a propósito, consulte o parágrafo "Multiplexação (mux_tunnels=N)").
Em circunstâncias normais, a grande maioria dos sistemas BSD não encontrará esse tipo de coisa. Somente o GhostBSD que será atualizado no segundo semestre de 2023 encontrará esse fenômeno.
Isso ocorre porque o GhostBSD adicionou esta linha ao /etc/sysctl.conf
:
kern.maxfiles=100000
Esta linha reduz o limite superior para muito menor que o valor correspondente no FreeBSD vanilla.
A solução é simples, basta deletar esta linha. Você também pode comentar.
Você também pode usar o comando sysctl kern.maxfiles=300000
para modificar temporariamente o valor do limite superior.
Como o número de arquivos abertos em sistemas Linux é limitado a 1.024, é fácil encontrar esse problema.
Solução temporária:
ulimit -n
para visualizar o valor de saídaulimit -n 300000
Solução permanente:
Edite /etc/security/limits.conf e adicione no final
* hard nofile 300000
* soft nofile 300000
root hard nofile 300000
root soft nofile 300000
Como os dados TCP precisam ser transmitidos, a validação dos dados não pode ser ignorada, assim como o próprio TCP.
Independentemente de estar criptografado ou não, o kcptube reduzirá o MTU em 2 bytes e acrescentará 2 bytes de dados.
Se a opção de criptografia tiver sido usada, os 2 bytes de dados anexados serão os IV gerados temporariamente.
Se você optar por não usar a função de criptografia, os dados anexados de 2 bytes serão o código de verificação, que é o XOR dos bits altos e baixos do CRC32.
Deve-se lembrar que o uso de códigos de verificação ainda não consegue evitar 100% de erros de conteúdo, e o mesmo se aplica ao próprio TCP. Se você realmente precisa ser preciso, habilite a opção de criptografia.
Embora o KCP Tube tenha uma função de "multiplexação", ele não é aberto ativamente por padrão. Sem esse recurso, para cada conexão de entrada aceita, é criada uma conexão de saída correspondente.
O motivo é evitar o QoS da operadora. No estado de multiplexação, uma vez que um determinado número de porta é QoS, outras sessões que compartilham o mesmo número de porta serão bloqueadas ao mesmo tempo até que o número da porta seja alterado.
As conexões são independentes entre si. Mesmo que um determinado número de porta seja QoS, apenas esta sessão será afetada e as outras sessões não serão afetadas.
A menos que o programa hospedado gere um grande número de conexões independentes. Neste caso, o KCP Tube criará um grande número de canais KCP, que consumirão mais recursos da CPU durante o processo de comunicação.
Se você realmente deseja usar a função "multiplexação", pode consultar as seguintes categorias:
Cenários adequados para usar "multiplexação":
Cenários onde a "multiplexação" não é necessária:
Quando a "Multiplexação" estiver habilitada, o KCPTube pré-criará N links e todas as novas conexões de entrada transmitirão dados dos links existentes em vez de criar novos links separadamente. Neste momento, o tempo limite do canal KCP é de 30 segundos.
De modo geral, definir `mux_tunnels para 3 ~ 10 é suficiente e não há necessidade de definir um valor muito alto.
Para reduzir a latência, kcptube habilita a opção TCP_NODELAY. Para alguns cenários de aplicações de grande tráfego, a quantidade de transmissão de dados TCP pode ser reduzida.
Com base no KCP original, foram feitas as seguintes modificações:
flush()
original primeiro transfere os dados a serem enviados para a fila de envio e, em seguida, refaz as três coisas de "enviar novos pacotes de dados", "reenviar pacotes de dados" e "enviar pacotes ACK" no mesmo ciclo. A versão modificada primeiro realiza "retransmissão de pacotes de dados" e "transmissão de pacotes ACK" e, em seguida, "transfere os dados a serem enviados para a fila de envio" e os envia durante o período de transferência.check()
original percorrerá a fila de envio novamente todas as vezes para encontrar o carimbo de data/hora de retransmissão do ponto alcançado. A versão modificada passa a ser: leia o primeiro carimbo de data/hora da tabela de mapeamento classificada, eliminando a etapa de pesquisa.Além disso, a versão original possui "bugs" e o kcptube também os terá. Por exemplo:
Então o kcptube criou um plano de suspensão mais óbvio. Para dados TCP, quando o limite de recepção for atingido (a fila está cheia), a recepção de dados TCP será suspensa até que haja espaço e depois retomada para dados UDP, o pacote será perdido diretamente quando o limite de recepção for atingido;
Esta limitação basicamente não terá impacto em cenários de aplicação onde o volume de transmissão não é grande.
O pool de threads usado pelo kcptube vem de BS::thread_pool, com algumas modificações para criptografia paralela e processamento de descriptografia durante múltiplas conexões.
O código é escrito de maneira muito casual e eu o escrevo onde penso, então o layout é confuso. Para ser preciso, é muito confuso.
Algumas linhas de código são tão longas quanto varas de bambu, principalmente porque eu estava com preguiça de mudar de linha para seguir a linha de pensamento ao escrever. Afinal, eu não uso vim/emacs. Quando uso um IDE, o tamanho do texto definido na área de código do IDE é diferente do tamanho do texto em outras áreas, e até as fontes são diferentes, o que me ajuda a aliviar o problema de confusão.
Quanto aos sentimentos dos leitores... eles definitivamente ficarão infelizes. Não é da minha conta, deixe isso pra lá.