xtaci / kcp-go

A Crypto-Secure Reliable-UDP Library for golang with FEC
MIT License
4.12k stars 737 forks source link

Why is UDPSession.SetWriteBuffer no effect if accepted from Listener? #226

Open zhiqiangxu opened 2 years ago

zhiqiangxu commented 2 years ago
// SetWriteBuffer sets the socket write buffer, no effect if it's accepted from Listener
func (s *UDPSession) SetWriteBuffer(bytes int) error {
    s.mu.Lock()
    defer s.mu.Unlock()
    if s.l == nil {
        if nc, ok := s.conn.(setWriteBuffer); ok {
            return nc.SetWriteBuffer(bytes)
        }
    }
    return errInvalidOperation
}

If UDPSession said to be a drop-in replacement for net.TCPConn, why is UDPSession.SetWriteBuffer no effect if accepted from Listener?

xtaci commented 2 years ago

because we only have one shared socket for UDP

zhiqiangxu commented 2 years ago

image

Today I made a test to compare the performance of quic/tcp/ws/http/grpc/kcp(this is the order of testcases, not the order of performance), each test sends and receives 100,000 requests/responses, all other logic is the same(they all fit into the qrpc framework), the only difference is how the raw bytes are read(each implementing net.Conn in its own way), as you can see in the above picture, it turns out kcp is the slowest. And there's a warning saying that calling SetWriteBuffer on a Accepted UDPSession is invalid operation.

The testcase for kcp is this one:https://github.com/zhiqiangxu/qrpc/blob/quic_and_kcp/test/qrpc_kcp_test.go#L80

After I tuned kcp.ListenWithOptions(address, nil, 0, 0) to kcp.ListenWithOptions(address, nil, 7, 3) in this commit, it still takes more than 6 seconds to finish all 100,000 requests/responses, slower than plain http.

Any advice is very appreciated!