### Serve KCP over Existing UDP Connection (Go) Source: https://context7.com/xtaci/kcp-go/llms.txt This Go snippet demonstrates how to serve KCP connections over an existing UDP connection. It's particularly useful when fine-grained control over the underlying UDP socket is required. Dependencies include the 'net' and 'github.com/xtaci/kcp-go/v5' packages. It takes a UDP connection as input and returns a KCP listener. ```go package main import ( "log" "net" "github.com/xtaci/kcp-go/v5" ) func main() { // Example 1: Serve KCP over existing UDP connection // Useful when you need fine-grained control over the socket udpAddr, err := net.ResolveUDPAddr("udp", ":9999") if err != nil { log.Fatal(err) } udpConn, err := net.ListenUDP("udp", udpAddr) if err != nil { log.Fatal(err) } // Configure UDP socket before passing to KCP udpConn.SetReadBuffer(4194304) // 4MB udpConn.SetWriteBuffer(4194304) // 4MB // ServeConn wraps existing connection (kcp-go will not close it) listener, err := kcp.ServeConn(nil, 10, 3, udpConn) if err != nil { log.Fatal(err) } defer listener.Close() log.Println("KCP serving on existing UDP connection") } ``` -------------------------------- ### Dial KCP Connection with Encryption and FEC (Go) Source: https://context7.com/xtaci/kcp-go/llms.txt This Go code snippet shows how a client can establish a KCP connection to a server. It uses the same key derivation and encryption method as the server and specifies matching FEC parameters. The client also configures low-latency KCP parameters, sets read/write deadlines, sends a message, receives a response, and prints connection statistics. ```Go package main import ( "crypto/sha1" "fmt" "log" "time" "github.com/xtaci/kcp-go/v5" "golang.org/x/crypto/pbkdf2" ) func main() { // Must use same key derivation as server key := pbkdf2.Key([]byte("my-secret-pass"), []byte("my-salt"), 4096, 32, sha1.New) block, err := kcp.NewAESBlockCrypt(key) if err != nil { log.Fatal(err) } // Connect with matching FEC parameters (10 data, 3 parity) conn, err := kcp.DialWithOptions("server.example.com:9999", block, 10, 3) if err != nil { log.Fatal(err) } defer conn.Close() // Configure for low latency (same as server) conn.SetNoDelay(1, 10, 2, 1) conn.SetStreamBuffer(4194304) conn.SetWindowSize(1024, 1024) // Set timeouts conn.SetReadDeadline(time.Now().Add(30 * time.Second)) conn.SetWriteDeadline(time.Now().Add(30 * time.Second)) // Send data message := []byte("Hello KCP!") if _, err := conn.Write(message); err != nil { log.Fatal(err) } // Receive response buf := make([]byte, 4096) n, err := conn.Read(buf) if err != nil { log.Fatal(err) } fmt.Printf("Received: %s\n", buf[:n]) // Get connection statistics fmt.Printf("Connection stats: %+v\n", conn.GetSnmp()) } ``` -------------------------------- ### Configure Encryption Algorithms with KCP-Go Source: https://context7.com/xtaci/kcp-go/llms.txt This Go code snippet shows how to configure various encryption algorithms (AES, Salsa20, TEA, Triple DES, None) for KCP connections. It uses PBKDF2 for key derivation and demonstrates how to create block ciphers, which can then be used with KCP's listener creation functions. ```go package main import ( "crypto/sha1" "log" "github.com/xtaci/kcp-go/v5" "golang.org/x/crypto/pbkdf2" ) func main() { password := []byte("secure-password") salt := []byte("random-salt") // AES-128: Best choice with hardware acceleration (AES-NI) // Fastest on modern CPUs, ~913 MB/s aesKey := pbkdf2.Key(password, salt, 4096, 16, sha1.New) aesBlock, err := kcp.NewAESBlockCrypt(aesKey) if err != nil { log.Fatal(err) } // Salsa20: Fast software encryption, ~906 MB/s // Good alternative when AES-NI not available salsa20Key := pbkdf2.Key(password, salt, 4096, 32, sha1.New) salsa20Block, err := kcp.NewSalsa20BlockCrypt(salsa20Key) if err != nil { log.Fatal(err) } // TEA: Lightweight encryption, ~195 MB/s // Lower CPU usage, suitable for embedded devices teaKey := pbkdf2.Key(password, salt, 4096, 16, sha1.New) teaBlock, err := kcp.NewTEABlockCrypt(teaKey) if err != nil { log.Fatal(err) } // Triple DES: Strong but slow, ~25 MB/s // Use only for compatibility requirements tripleDesKey := pbkdf2.Key(password, salt, 4096, 24, sha1.New) tripleDesBlock, err := kcp.NewTripleDESBlockCrypt(tripleDesKey) if err != nil { log.Fatal(err) } // No encryption: Maximum throughput, ~65597 MB/s // Only use in trusted networks or when upper layer handles encryption noneBlock, err := kcp.NewNoneBlockCrypt(nil) if err != nil { log.Fatal(err) } // Use any block cipher with ListenWithOptions or DialWithOptions listener, err := kcp.ListenWithOptions(":8888", aesBlock, 10, 3) if err != nil { log.Fatal(err) } defer listener.Close() log.Printf("Server started with AES encryption") // Alternative ciphers can be passed to create different listeners _ = salsa20Block _ = teaBlock _ = tripleDesBlock _ = noneBlock } ``` -------------------------------- ### Configure KCP-Go Stream Mode and Buffers in Go Source: https://context7.com/xtaci/kcp-go/llms.txt Demonstrates setting KCP-Go connections to stream mode for efficient bulk data transfer and message mode for discrete packets. It covers `SetStreamBuffer`, `SetReadBuffer`, `SetWriteBuffer`, and showcases reading with `io.ReadFull` and `io.Copy`. Optimal for bulk data transfers and file operations. ```go package main import ( "io" "log" "github.com/xtaci/kcp-go/v5" ) func main() { conn, err := kcp.Dial("server.example.com:9999") if err != nil { log.Fatal(err) } defer conn.Close() // SetStreamBuffer enables stream mode with automatic buffering // Accumulates small writes into larger packets to improve efficiency // Essential for bulk data transfers and file operations // // size: Maximum bytes to buffer before flushing (default: 4MB) // Set to 0 to disable stream buffering (message mode) // Stream mode: Optimal for continuous data flow // Use case: File transfer, video streaming, database synchronization conn.SetStreamBuffer(4194304) // 4MB buffer // Example: Efficient file transfer with stream mode file := make([]byte, 100*1024*1024) // 100MB file // Writes are buffered and sent in optimal packet sizes for i := 0; i < len(file); i += 8192 { end := i + 8192 if end > len(file) { end = len(file) } n, err := conn.Write(file[i:end]) if err != nil { log.Fatal(err) } _ = n } // Message mode: Optimal for discrete messages // Use case: RPC, command-response protocols, gaming packets conn.SetStreamBuffer(0) // Disable buffering // Each write becomes a distinct message/packet messages := [][]byte{ []byte("MESSAGE_1"), []byte("MESSAGE_2"), []byte("MESSAGE_3"), } for _, msg := range messages { // Each write is sent immediately as individual packet if _, err := conn.Write(msg); err != nil { log.Fatal(err) } } // Configure read buffer behavior conn.SetReadBuffer(4194304) // OS-level socket buffer: 4MB conn.SetWriteBuffer(4194304) // OS-level socket buffer: 4MB // Reading in stream mode: Read() may return partial data buf := make([]byte, 4096) n, err := conn.Read(buf) if err != nil && err != io.EOF { log.Fatal(err) } log.Printf("Read %d bytes (may be partial)", n) // Read exact amount using io.ReadFull exact := make([]byte, 1024) if _, err := io.ReadFull(conn, exact); err != nil { log.Fatal(err) } log.Printf("Read exactly %d bytes", len(exact)) // Using io.Copy for bulk streaming // Automatically uses optimal buffer sizes writer := &dataWriter{} written, err := io.Copy(writer, conn) if err != nil { log.Fatal(err) } log.Printf("Streamed %d bytes", written) } type dataWriter struct { total int64 } func (w *dataWriter) Write(p []byte) (n int, err error) { w.total += int64(len(p)) return len(p), nil } ``` -------------------------------- ### Configure kcp-go Listeners with FEC Options Source: https://context7.com/xtaci/kcp-go/llms.txt Demonstrates how to create kcp-go listeners with different Forward Error Correction (FEC) configurations. Each configuration specifies the number of data shards and parity shards, influencing recovery capability and bandwidth overhead. It covers settings from no FEC to maximum FEC, and efficient FEC with larger shard groups. ```go package main import ( "log" "github.com/xtaci/kcp-go/v5" ) func main() { // FEC parameters: (dataShards, parityShards) // // dataShards: Number of original data packets in a group // parityShards: Number of redundant parity packets generated // // Recovery capability: Can recover from up to 'parityShards' packet losses // Bandwidth overhead: parityShards / dataShards * 100% // // Example: (10, 3) = 30% overhead, recovers from 3 packet losses per 10 packets // Conservative FEC: 20% overhead, handles up to 2 lost packets per 10 // Good for: Domestic connections, stable networks listener1, err := kcp.ListenWithOptions(":8001", nil, 10, 2) if err != nil { log.Fatal(err) } defer listener1.Close() // Moderate FEC: 30% overhead, handles up to 3 lost packets per 10 // Good for: International connections, moderate packet loss (1-3%) listener2, err := kcp.ListenWithOptions(":8002", nil, 10, 3) { if err != nil { log.Fatal(err) } defer listener2.Close() // Aggressive FEC: 50% overhead, handles up to 5 lost packets per 10 // Good for: Intercontinental, high-loss networks (3-10% loss) listener3, err := kcp.ListenWithOptions(":8003", nil, 10, 5) { if err != nil { log.Fatal(err) } defer listener3.Close() // Maximum FEC: 100% overhead, handles up to 10 lost packets per 10 // Good for: Extreme conditions, satellite, very unstable links listener4, err := kcp.ListenWithOptions(":8004", nil, 10, 10) { if err != nil { log.Fatal(err) } defer listener4.Close() // No FEC: No overhead, relies on KCP retransmission only // Good for: Local network, low latency requirements, stable connections listener5, err := kcp.ListenWithOptions(":8005", nil, 0, 0) { if err != nil { log.Fatal(err) } defer listener5.Close() // Efficient FEC: Larger shard groups reduce overhead // (20, 3) = 15% overhead instead of 30% with (10, 3) // Trade-off: Increased latency due to larger batching window listener6, err := kcp.ListenWithOptions(":8006", nil, 20, 3) { if err != nil { log.Fatal(err) } defer listener6.Close() log.Println("FEC-enabled listeners started on ports 8001-8006") // Client must use matching FEC parameters conn, err := kcp.DialWithOptions("server:8002", nil, 10, 3) if err != nil { log.Fatal(err) } defer conn.Close() // Monitor FEC effectiveness stats := conn.GetSnmp() log.Printf("FEC recovered %d packets out of %d parity shards", stats.FECRecovered, stats.FECParityShards) if stats.FECErrs > 0 { log.Printf("Warning: FEC failed to recover %d packets (increase parity shards)", stats.FECErrs) } } ``` -------------------------------- ### Control KCP Buffer Sizes and QoS Settings (Go) Source: https://context7.com/xtaci/kcp-go/llms.txt This Go snippet illustrates how to control the read and write buffer sizes, as well as set the Differentiated Services Code Point (DSCP) for Quality of Service (QoS) on a KCP listener. It utilizes the 'log' and 'github.com/xtaci/kcp-go/v5' packages. Input is a KCP listener, and it configures its network parameters. ```go package main import ( "log" "github.com/xtaci/kcp-go/v5" ) func main() { // Assume 'listener' is an existing kcp.Listener // Example 3: Control buffer sizes and QoS settings listener, _ := kcp.ServeConn(nil, 10, 3, nil) // Placeholder for illustration listener.SetReadBuffer(8388608) // 8MB read buffer listener.SetWriteBuffer(8388608) // 8MB write buffer listener.SetDSCP(46) // Set DSCP for QoS (EF - Expedited Forwarding) log.Println("KCP listener buffer sizes and DSCP configured.") listener.Close() } ``` -------------------------------- ### Accept KCP Connections with Timeout (Go) Source: https://context7.com/xtaci/kcp-go/llms.txt This Go snippet demonstrates how to accept KCP connections with a specified timeout. It handles potential timeout errors gracefully and logs the remote address of accepted connections. Dependencies include 'log', 'net', and 'github.com/xtaci/kcp-go/v5'. It takes a KCP listener and returns an accepted KCP connection or an error. ```go package main import ( "log" "net" "time" "github.com/xtaci/kcp-go/v5" ) func main() { // Assume 'listener' is an existing kcp.Listener // Example 4: Accept connections with timeout listener, _ := kcp.ServeConn(nil, 10, 3, nil) // Placeholder for illustration listener.SetDeadline(time.Now().Add(30 * time.Second)) conn, err := listener.AcceptKCP() if err != nil { if netErr, ok := err.(net.Error); ok && netErr.Timeout() { log.Println("Accept timeout") } else { log.Fatal(err) } } else { defer conn.Close() // Get remote address log.Printf("Accepted connection from: %s", conn.RemoteAddr()) // Check if connection owns its underlying socket log.Printf("Connection owns socket: %v", conn.GetConv() != 0) } listener.Close() } ``` -------------------------------- ### Monitor KCP Connection Statistics in Go Source: https://context7.com/xtaci/kcp-go/llms.txt This Go code snippet demonstrates how to establish a KCP connection, send data, and then retrieve detailed per-connection SNMP statistics. It covers metrics for data transfer, reliability, Forward Error Correction (FEC), and errors, as well as system-wide statistics. It also includes a goroutine to periodically print updated connection statistics. ```go package main import ( "fmt" "log" "time" "github.com/xtaci/kcp-go/v5" ) func main() { conn, err := kcp.Dial("server.example.com:9999") if err != nil { log.Fatal(err) } defer conn.Close() // Perform some data transfer data := make([]byte, 1024*1024) // 1MB conn.Write(data) // Get per-connection statistics stats := conn.GetSnmp() fmt.Println("=== Connection Statistics ===") fmt.Printf("Bytes Sent: %d\n", stats.BytesSent) fmt.Printf("Bytes Received: %d\n", stats.BytesReceived) fmt.Printf("Packets In: %d\n", stats.InPkts) fmt.Printf("Packets Out: %d\n", stats.OutPkts) fmt.Printf("UDP Bytes In: %d\n", stats.InBytes) fmt.Printf("UDP Bytes Out: %d\n", stats.OutBytes) fmt.Println("\n=== Reliability Metrics ===") fmt.Printf("Retransmitted Segments: %d\n", stats.RetransSegs) fmt.Printf("Fast Retransmissions: %d\n", stats.FastRetransSegs) fmt.Printf("Early Retransmissions: %d\n", stats.EarlyRetransSegs) fmt.Printf("Lost Segments (inferred): %d\n", stats.LostSegs) fmt.Printf("Duplicate Segments: %d\n", stats.RepeatSegs) fmt.Println("\n=== FEC Statistics ===") fmt.Printf("FEC Packets Recovered: %d\n", stats.FECRecovered) fmt.Printf("FEC Recovery Errors: %d\n", stats.FECErrs) fmt.Printf("FEC Parity Shards Sent: %d\n", stats.FECParityShards) fmt.Printf("Complete Shard Sets: %d\n", stats.FECFullShardSet) fmt.Println("\n=== Error Statistics ===") fmt.Printf("Input Errors: %d\n", stats.InErrs) fmt.Printf("Checksum Errors: %d\n", stats.InCsumErrors) fmt.Printf("KCP Protocol Errors: %d\n", stats.KCPInErrors) // Calculate derived metrics if stats.OutPkts > 0 { retransRate := float64(stats.RetransSegs) / float64(stats.OutSegs) * 100 fmt.Printf("\nRetransmission Rate: %.2f%%\n", retransRate) } if stats.FECParityShards > 0 { fecRecoveryRate := float64(stats.FECRecovered) / float64(stats.FECParityShards) * 100 fmt.Printf("FEC Recovery Rate: %.2f%%\n", fecRecoveryRate) } // Get default system-wide statistics defaultSnmp := kcp.DefaultSnmp.Copy() fmt.Printf("\n=== System-Wide Statistics ===\n") fmt.Printf("Current Connections: %d\n", defaultSnmp.CurrEstab) fmt.Printf("Max Connections: %d\n", defaultSnmp.MaxConn) fmt.Printf("Active Opens: %d\n", defaultSnmp.ActiveOpens) fmt.Printf("Passive Opens: %d\n", defaultSnmp.PassiveOpens) // Monitor statistics over time go func() { ticker := time.NewTicker(5 * time.Second) defer ticker.Stop() for range ticker.C { s := conn.GetSnmp() fmt.Printf("[%s] TX: %d bytes, RX: %d bytes, Retrans: %d\n", time.Now().Format("15:04:05"), s.BytesSent, s.BytesReceived, s.RetransSegs, ) } }() time.Sleep(30 * time.Second) } ``` -------------------------------- ### Tune KCP Performance Parameters with KCP-Go Source: https://context7.com/xtaci/kcp-go/llms.txt This Go code snippet illustrates how to tune KCP's performance parameters using the SetNoDelay function and other methods like SetWindowSize, SetStreamBuffer, SetMtu, and SetACKNoDelay. These settings allow for balancing latency, throughput, and reliability based on application needs. ```go package main import ( "log" "github.com/xtaci/kcp-go/v5" ) func main() { conn, err := kcp.Dial("server.example.com:9999") if err != nil { log.Fatal(err) } defer conn.Close() // SetNoDelay(nodelay, interval, resend, nc) // // nodelay: 0=disable, 1=enable no-delay mode // Affects RTO calculation: disabled uses normal min RTO (100ms), // enabled uses no-delay min RTO (30ms) // // interval: Internal update interval in milliseconds (10-100) // Lower = more CPU, lower latency; Higher = less CPU, higher latency // // resend: Fast resend mode // 0=disabled, 1=enabled (resend after 1 dup ACK), 2=enabled (resend after 2 dup ACKs) // // nc: Congestion control // 0=enabled (normal mode), 1=disabled (ignore slow start/congestion window) // Preset 1: Normal mode - balanced latency and bandwidth // Good for general purpose applications conn.SetNoDelay(0, 40, 0, 1) // Preset 2: Fast mode - optimized for low latency // Recommended for gaming, VoIP, real-time applications // Increases bandwidth usage by ~20-40% conn.SetNoDelay(1, 10, 2, 1) // Preset 3: Ultra-fast mode - minimal latency at any cost // For extremely latency-sensitive applications // Can increase bandwidth usage by 50-100% conn.SetNoDelay(1, 5, 2, 1) // Preset 4: Slow mode - minimize CPU/bandwidth usage // For high connection counts (>5000) or low-power devices // Trades latency for system resources conn.SetNoDelay(0, 100, 0, 1) // Set send/receive window sizes (packets) // Larger windows = higher throughput but more memory // Default: 32 packets each conn.SetWindowSize(128, 128) // Normal conn.SetWindowSize(512, 512) // High throughput conn.SetWindowSize(1024, 1024) // Maximum throughput // Set stream mode buffer size (bytes) // Accumulates small writes into larger packets // Default: 4MB recommended for bulk transfers conn.SetStreamBuffer(4194304) // Set MTU and maximum segment size // Smaller MTU = less packet loss impact, more overhead // Larger MTU = better throughput, worse loss impact // Default: 1400 bytes (safe for most networks) conn.SetMtu(1400) // Default, works everywhere conn.SetMtu(1200) // Conservative, for poor networks conn.SetMtu(9000) // Jumbo frames, LAN only // Enable ACK acknowledgment without delay (testing/debugging) conn.SetACKNoDelay(false) // Normal: batch ACKs conn.SetACKNoDelay(true) // Immediate: send ACK per packet log.Println("KCP parameters configured") } ``` -------------------------------- ### Set Connection Timeouts and Deadlines in Go Source: https://context7.com/xtaci/kcp-go/llms.txt This Go code snippet demonstrates setting overall, read, and write deadlines for a kcp connection. It shows how to handle timeout errors for both read and write operations, and how to clear deadlines. Useful for managing connection health and preventing indefinite blocking. ```go package main import ( "io" "log" "net" "time" "github.com/xtaci/kcp-go/v5" ) func main() { conn, err := kcp.Dial("server.example.com:9999") if err != nil { log.Fatal(err) } defer conn.Close() // Set overall deadline for both read and write operations // Deadline is an absolute time point conn.SetDeadline(time.Now().Add(30 * time.Second)) // Set separate read deadline // Useful for implementing read timeouts in servers conn.SetReadDeadline(time.Now().Add(10 * time.Second)) buf := make([]byte, 1024) n, err := conn.Read(buf) if err != nil { if netErr, ok := err.(net.Error); ok && netErr.Timeout() { log.Println("Read timeout - no data received within 10 seconds") } else if err == io.EOF { log.Println("Connection closed by peer") } else { log.Fatal(err) } } else { log.Printf("Read %d bytes: %s", n, buf[:n]) } // Set write deadline // Prevents blocking indefinitely if peer's receive window is full conn.SetWriteDeadline(time.Now().Add(5 * time.Second)) data := make([]byte, 1024*1024) // 1MB _, err = conn.Write(data) if err != nil { if netErr, ok := err.(net.Error); ok && netErr.Timeout() { log.Println("Write timeout - peer not consuming data fast enough") } else { log.Fatal(err) } } // Clear deadline by setting to zero value // Future operations will not timeout conn.SetDeadline(time.Time{}) // Pattern 1: Heartbeat with timeout go func() { ticker := time.NewTicker(10 * time.Second) defer ticker.Stop() for range ticker.C { conn.SetWriteDeadline(time.Now().Add(5 * time.Second)) if _, err := conn.Write([]byte("PING")); err != nil { log.Println("Heartbeat failed, closing connection") conn.Close() return } } }() // Pattern 2: Request-response with timeout request := []byte("GET /data") conn.SetWriteDeadline(time.Now().Add(3 * time.Second)) if _, err := conn.Write(request); err != nil { log.Fatal("Request failed:", err) } response := make([]byte, 4096) conn.SetReadDeadline(time.Now().Add(10 * time.Second)) n, err = conn.Read(response) if err != nil { log.Fatal("Response timeout:", err) } log.Printf("Response: %s", response[:n]) // Pattern 3: Server accept with timeout listener, err := kcp.Listen(":9999") if err != nil { log.Fatal(err) } defer listener.Close() // Accept will timeout after 30 seconds listener.SetDeadline(time.Now().Add(30 * time.Second)) acceptedConn, err := listener.Accept() if err != nil { if netErr, ok := err.(net.Error); ok && netErr.Timeout() { log.Println("No connections within 30 seconds") } else { log.Fatal(err) } } else { acceptedConn.Close() } } ``` -------------------------------- ### Slice vs. List Performance Benchmark (Go) Source: https://github.com/xtaci/kcp-go/blob/master/README.md Compares the performance of iterating over a Go slice versus a container/list data structure. The benchmark highlights the significant performance difference due to cache misses associated with list structures compared to the better locality of slices. ```Go package benchmark2 import "testing" var data = make([]int, 1000) // Placeholder for a list-like structure type Node struct { next *Node; val int } var listHead *Node func BenchmarkLoopSlice(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { for _, v := range data { _ = v } } } func BenchmarkLoopList(b *testing.B) { // Initialize list for benchmark listHead = &Node{} curr := listHead for i := 0; i < 1000; i++ { curr.next = &Node{val: i} curr = curr.next } b.ResetTimer() for i := 0; i < b.N; i++ { curr := listHead.next for curr != nil { _ = curr.val curr = curr.next } } } ``` -------------------------------- ### Create KCP Listener with Encryption and FEC (Go) Source: https://context7.com/xtaci/kcp-go/llms.txt This Go code snippet demonstrates how to create a KCP listener that accepts incoming UDP connections. It configures AES encryption using a derived key and enables Forward Error Correction (FEC) with specified data and parity shards. The listener is set up to handle connections in separate goroutines and configures KCP parameters for low latency. ```Go package main import ( "crypto/sha1" "io" "log" "github.com/xtaci/kcp-go/v5" "golang.org/x/crypto/pbkdf2" ) func main() { // Derive encryption key from password key := pbkdf2.Key([]byte("my-secret-pass"), []byte("my-salt"), 4096, 32, sha1.New) // Create AES block cipher for encryption block, err := kcp.NewAESBlockCrypt(key) if err != nil { log.Fatal(err) } // Listen with FEC: 10 data shards, 3 parity shards // This means for every 10 data packets, 3 redundant parity packets are sent listener, err := kcp.ListenWithOptions("0.0.0.0:9999", block, 10, 3) if err != nil { log.Fatal(err) } defer listener.Close() log.Println("KCP server listening on :9999") for { // Accept incoming KCP connections conn, err := listener.AcceptKCP() if err != nil { log.Printf("Accept error: %v", err) continue } // Handle connection in goroutine go handleConnection(conn) } } func handleConnection(conn *kcp.UDPSession) { defer conn.Close() // Configure KCP parameters for low latency // nodelay=1: enable no-delay mode // interval=10: internal update interval in ms // resend=2: fast resend mode // nc=1: disable congestion control conn.SetNoDelay(1, 10, 2, 1) // Set stream buffer sizes conn.SetStreamBuffer(4194304) // 4MB buffer conn.SetWindowSize(1024, 1024) // send/recv window buf := make([]byte, 4096) for { n, err := conn.Read(buf) if err != nil { if err != io.EOF { log.Printf("Read error: %v", err) } return } // Echo back if _, err := conn.Write(buf[:n]); err != nil { log.Printf("Write error: %v", err) return } } } ``` -------------------------------- ### System Time Call Benchmark (Go) Source: https://github.com/xtaci/kcp-go/blob/master/README.md Measures the performance overhead of calling the system's time function (`time.Now()`) in Go. This benchmark is relevant for understanding the cost of obtaining timestamps, which is critical for network protocols like KCP that rely on accurate timing for RTT estimation. ```Go package benchmark2 import ( "testing" "time" ) func BenchmarkNow(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { time.Now() } } ``` -------------------------------- ### Manage KCP Session Lifecycle with Auto-Close (Go) Source: https://context7.com/xtaci/kcp-go/llms.txt This Go snippet shows how to manage KCP session lifecycles, including accepting new connections and automatically closing them after a period of inactivity. It uses goroutines for concurrent handling and timers for inactivity detection. Dependencies include 'log', 'net', 'time', and 'github.com/xtaci/kcp-go/v5'. It processes incoming KCP connections and manages their active state. ```go package main import ( "log" "net" "time" "github.com/xtaci/kcp-go/v5" ) func main() { // Assume 'listener' is an existing kcp.Listener // Example 5: Close specific session from listener // Useful for connection management and cleanup listener, _ := kcp.ServeConn(nil, 10, 3, nil) // Placeholder for illustration go func() { for { c, err := listener.AcceptKCP() if err != nil { return } // Handle with timeout go func(conn *kcp.UDPSession) { defer conn.Close() // Auto-close after 5 minutes of inactivity timer := time.AfterFunc(5*time.Minute, func() { conn.Close() }) defer timer.Stop() buf := make([]byte, 4096) for { conn.SetReadDeadline(time.Now().Add(5 * time.Minute)) n, err := conn.Read(buf) if err != nil { return } timer.Reset(5 * time.Minute) conn.Write(buf[:n]) } }(c) } }() log.Println("KCP session management started.") select {} // Keep main goroutine alive // listener.Close() // This would typically be called on application shutdown } ``` -------------------------------- ### Create KCP Session with Custom Conversation ID (Go) Source: https://context7.com/xtaci/kcp-go/llms.txt This Go snippet shows how to create a KCP session with a custom conversation ID. This is beneficial for multiplexing or implementing custom session management logic. It requires the 'crypto/rand', 'encoding/binary', 'log', 'net', and 'github.com/xtaci/kcp-go/v5' packages. It takes a conversation ID, remote address, and an underlying UDP connection as input, returning a KCP session. ```go package main import ( "crypto/rand" "encoding/binary" "log" "net" "github.com/xtaci/kcp-go/v5" ) func main() { // Example 2: Create KCP session with custom conversation ID // Useful for multiplexing or custom session management var convID uint32 binary.Read(rand.Reader, binary.LittleEndian, &convID) remoteAddr, err := net.ResolveUDPAddr("udp", "server.example.com:9999") if err != nil { log.Fatal(err) } localConn, err := net.ListenUDP("udp", nil) if err != nil { log.Fatal(err) } // Create session with specific conversation ID and own connection management session, err := kcp.NewConn4(convID, remoteAddr, nil, 10, 3, false, localConn) if err != nil { log.Fatal(err) } defer session.Close() log.Printf("Created KCP session with conversation ID: %d", convID) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.