kcp-go icon indicating copy to clipboard operation
kcp-go copied to clipboard

real speed is 71kb/sec ?

Open fardeadok opened this issue 1 year ago • 1 comments

I wrote some code for the test and it turned out that if the delay is less than 14ms in line 51, then the receiver receives a different number of bytes each time! i.e. it loses packets somewhere?

It turns out that with a delay of 14ms and a packet size of 1024 bytes, the total speed of this KCP is about 71kb/sec ? Isn't that too little? Tell me if I wrote everything correctly in the code.

sender code:


import (
	"crypto/sha1"
	"io"
	"log"
	"os"
	"time"

	"github.com/xtaci/kcp-go/v5"
	"golang.org/x/crypto/pbkdf2"
)

var EOFPACKET = []byte{1023: 0} // 1024 bytes of 0

func main() {

	file, _ := os.Open("data.css") // size 236 530 bytes
	defer file.Close()

	sender("192.168.154.200:12345", "superpass", "salt", 1024, 32, file)

	println("ctrl c for exit")
	<-make(chan struct{}) // wait
}

// *   127.0.0.1  12345        superpass  salt                 1024            32
func sender(hostport string, kcp_pass, kcp_salt string, kcp_iterations, kcp_keylen int, DATA io.Reader) error {

	key := pbkdf2.Key([]byte(kcp_pass), []byte(kcp_salt), kcp_iterations, kcp_keylen, sha1.New)

	block, _ := kcp.NewAESBlockCrypt(key)

	sess, err := kcp.DialWithOptions(hostport, block, 10, 3)
	if err != nil {
		log.Fatal("error dialing:", err)
	}

	defer sess.Close()

	dataBuf := make([]byte, 1024)

	totalLen := 0

	// written, err := io.Copy(sess, DATA) // lost packets every time
	// println("written bytes:", written, " error:", err)
	// return nil

	for {
		println()
		time.Sleep(14 * time.Millisecond)

		// read from file
		n, e := DATA.Read(dataBuf)
		if e == io.EOF {
			println("EOF")
			break
		}

		if e != nil {
			println("error read:", e)
			break
		}

		// println("read n:", n)
		totalLen += n
		println("read bytes:", n, " total read data:", totalLen)

		// println(string(dataBuf[:n]))

		sn, es := sess.Write(dataBuf[:n])
		if es != nil {
			log.Println("error sending:", es)
			break
		}

		println("sent bytes:", sn)

	}

	println("end of sender")

	// send exit to session
	sess.Write(EOFPACKET)

	return nil
}

receiver code:

package main

import (
	"crypto/sha1"
	"fmt"
	"log"
	"slices"
	"time"

	"github.com/xtaci/kcp-go/v5"
	"golang.org/x/crypto/pbkdf2"
)

var EOFPACKET = []byte{1023: 0} // 1024 bytes of 0

func main() {
	// *   127.0.0.1  12345        superpass  salt                 1024            32

	key := pbkdf2.Key([]byte("superpass"), []byte("salt"), 1024, 32, sha1.New)
	block, _ := kcp.NewAESBlockCrypt(key)

	if listener, err := kcp.ListenWithOptions(":12345", block, 10, 3); err == nil {

		for {
			session, err := listener.AcceptKCP()
			if err != nil {
				log.Fatal(err)
			}
			go receiver(session)
		}

	} else {
		log.Fatal(err)
	}

}

func receiver(conn *kcp.UDPSession) {
	var bufSum []byte
	buf := make([]byte, 1024)

	timeNow := time.Now()

	for {

		n, err := conn.Read(buf)
		// fmt.Printf("Received bytes %d: %s\n", n, buf[:n])
		// fmt.Printf("Received bytes %d: \n", n)

		if slices.Equal(buf, EOFPACKET) {
			println("___________________ receive EOFPACKET!")
			break
		}

		if err != nil {
			log.Println("___________________ WTF?:", err)
			break
		}

		bufSum = append(bufSum, buf[:n]...)
		// println("total bufSum len:", len(bufSum))

	}

	conn.Close()
	println("total bufSum len:", len(bufSum))

	timeDiff := time.Since(timeNow)
	sec := timeDiff.Seconds()
	fmt.Printf("timeDiff: %f\n", sec)

	bandwidth := float64(len(bufSum)) / sec

	fmt.Printf("bandwidth: %f bytes/sec \n", bandwidth)

	println("end of receiver")
}

output is:

___________________ receive EOFPACKET!
total bufSum len: 236530
timeDiff: 3.493266
bandwidth: 67710.282961 bytes/sec 
end of receiver

fardeadok avatar Jul 24 '24 10:07 fardeadok

https://github.com/xtaci/kcp-go/blob/master/sess_test.go#L432-L464

xtaci avatar Jul 24 '24 14:07 xtaci