Overview of kcp-go
masternet.Conn and net.Listener interfaces, making it a drop-in replacement for net.TCPConn.repository·master·Indexed 26 days ago
https://github.com/xtaci/kcp-goA high-performance, Reliable-UDP library for Go designed for latency-sensitive applications such as gaming and live broadcasting. It implements net.Conn and net.Listener interfaces for compatibility with Go's standard networking, featuring Forward Error Correction (FEC) using Reed-Solomon Codes and various packet-level encryption options including AES, Salsa20, and AEAD. The library is optimized for scalability, supporting over 5,000 concurrent connections per server.
net.Conn and net.Listener interfaces, making it a drop-in replacement for net.TCPConn.kcp-go includes the following features:
net.Conn and net.Listener.sendmmsg and recvmmsg on Linux.kcp_dissector.lua file into the Wireshark PlugIns directory within the application bundle.Enable FEC for long-distance transmissions. In complex routing networks, packet loss incurs significant time penalties. Because RTT samples can deviate significantly over long distances, typical RTT estimators may result in a larger RTO (Retransmission TimeOut), slowing down transmission. FEC helps mitigate this.
It is recommended to enable encryption for protocol security, even if your upper-layer application already implements encryption.
When using kcp-go, keep the following security aspects in mind:
AES-128) makes the entire packet (including headers, FEC, and checksums) anonymous. If encryption is disabled, the header is sent in plaintext and is susceptible to tampering (e.g., jamming sliding window size, RTT, or checksums).smux to mix data streams and introduce noise can help mitigate this.KCP does not define control messages like TCP's SYN/FIN/RST. To detect or manage connection termination, you must implement a keepalive/heartbeat mechanism at the application level.
A recommended approach is to use a multiplexing protocol over the KCP session, such as smux, which includes an embedded keepalive mechanism.
Use Listen or ListenWithOptions to start a KCP server that listens for incoming UDP packets. You can specify encryption and Forward Error Correction (FEC) parameters.
Listen(laddr string): Listens on the provided address without encryption or FEC.ListenWithOptions(laddr string, block BlockCrypt, dataShards, parityShards int): Listens with optional encryption (block) and FEC (dataShards and parityShards).For FEC details, refer to the reedsolomon implementation.
If you are handling a large number of connections (>5K) and experiencing high CPU utilization, consider the following:
SetNoDelay interval: Increasing the update interval via SetNoDelay can dramatically reduce system load, though it may impact performance. For example, using conn.SetNoDelay(1, 40, 1, 1) increases the interval.You can run the built-in benchmarks to evaluate the performance of various encryption algorithms (e.g., AES, Salsa20, SM4), FEC (Forward Error Correction) encoding/decoding, and throughput speeds (Echo/Sink) on your specific hardware. Use the standard Go testing tool with the -bench flag.
$ go test -v -run=^$ -bench .The KCP protocol uses a specific frame format for transmission. The frame includes a nonce, CRC32 checksum, FEC information, and the KCP header.
Nonce: 16 bytes of cryptographically secure random numbers (changes every packet). CRC32: CRC-32 checksum of data using the IEEE polynomial. FEC TYPE:
typeData = 0xF1typeParity = 0xF2
FEC SEQID: Monotonically increasing range: [0, (0xffffffff/shardSize) * shardSize - 1]
SIZE: The size of the KCP frame plus 2.| Field | Type |
|---|---|
conv | u32 |
cmd | u8 |
frag | u8 |
wnd | u16 |
ts | u32 |
sn | u32 |
una | u32 |
data | bytes |
KCP Header
+------------------------------+
| conv (u32) |
+-------+-------+--------------+
| cmd | frag | wnd |
| u8 | u8 | u16 |
+-------+-------+--------------+
| ts (u32) |
+------------------------------+
| sn (u32) |
+------------------------------+
| una (u32) |
+------------------------------+
| data (bytes) |
+------------------------------+If you require a C++ implementation or related tools:
Use NewKCP to create a new KCP protocol instance. The conv (conversation ID) must be identical for both peers in a connection, otherwise data will be rejected. You must provide an output_callback function which the KCP engine will call whenever it has data to be sent over the network.
output_callback signature: func(buf []byte, size int)