kcp 協議的 Golang 實現庫

kcp-go 是 Golang 實現的 kcp 協議庫,它是可靠的 UDP 庫。

該庫 kcp-go 旨在通過 UDP 數據包提供流暢、有彈性、有序、經過錯誤檢查和匿名的流傳遞。該庫和開源項目 kcptun 經過了戰鬥測試。從低端 MIPS 路由器到高端服務器,數以百萬計的設備在各種應用中部署了基於 kcp-go 驅動的程序。包括在線遊戲、直播、文件同步和網絡加速。

我們介紹一下 kcp 協議,kcp 協議是一種快速可靠的 ARQ 協議,它以比 TCP 浪費 10%~20% 的帶寬爲代價,換取平均延遲降低 30%~40%,且最大延遲降低三倍的傳輸效果。它是純算法實現,並不負責底層協議(如 UDP)的收發,需要使用者自己定義下層數據包的發送方式,以 callback 的方式提供給 KCP。時鐘也是外部提供,內部不會有任何一次系統調用。KCP 協議已經通過使用 C 語言實現,整個協議只包含 ikcp.h,ikcp.c 兩個源文件,可以方便的集成到用戶自己的協議棧中。更多 kcp 內容請參考 kcp Github 項目(https://github.com/skywind3000/kcp)。

kcp-go 項目的特性:

kcp-go 規格:

kcp-go 簡單使用,回聲示例:

package main
import (
	"crypto/sha1"
	"io"
	"log"
	"time"
	"github.com/xtaci/kcp-go/v5"
	"golang.org/x/crypto/pbkdf2"
)
func main() {
	key := pbkdf2.Key([]byte("demo pass"), []byte("demo salt"), 1024, 32, sha1.New)
	block, _ := kcp.NewAESBlockCrypt(key)
	if listener, err := kcp.ListenWithOptions("127.0.0.1:12345", block, 10, 3); err == nil {
		// spin-up the client
		go client()
		for {
			s, err := listener.AcceptKCP()
			if err != nil {
				log.Fatal(err)
			}
			go handleEcho(s)
		}
	} else {
		log.Fatal(err)
	}
}
// handleEcho send back everything it received
func handleEcho(conn *kcp.UDPSession) {
	buf := make([]byte, 4096)
	for {
		n, err := conn.Read(buf)
		if err != nil {
			log.Println(err)
			return
		}
		n, err = conn.Write(buf[:n])
		if err != nil {
			log.Println(err)
			return
		}
	}
}
func client() {
	key := pbkdf2.Key([]byte("demo pass"), []byte("demo salt"), 1024, 32, sha1.New)
	block, _ := kcp.NewAESBlockCrypt(key)
	// wait for server to become ready
	time.Sleep(time.Second)
	// dial to the echo server
	if sess, err := kcp.DialWithOptions("127.0.0.1:12345", block, 10, 3); err == nil {
		for {
			data := time.Now().String()
			buf := make([]byte, len(data))
			log.Println("sent:", data)
			if _, err := sess.Write([]byte(data)); err == nil {
				// read back the data
				if _, err := io.ReadFull(sess, buf); err == nil {
					log.Println("recv:", string(buf))
				} else {
					log.Fatal(err)
				}
			} else {
				log.Fatal(err)
			}
			time.Sleep(time.Second)
		}
	} else {
		log.Fatal(err)
	}
}

TCP 中的 SYN/FIN/RST 等控制消息在 KCP 中沒有定義。您需要在應用程序級別使用保活 / 心跳機制。一個真實的例子是在會話上使用多路複用協議,例如 smux(它具有嵌入式保活機制)。

更多內容,請參考 Github 地址:

https://github.com/xtaci/kcp-go

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/yPkbVfozaTNdlXcaLE9-SA