Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected behavior #18

Closed
AudriusButkevicius opened this issue Aug 9, 2016 · 4 comments
Closed

Unexpected behavior #18

AudriusButkevicius opened this issue Aug 9, 2016 · 4 comments

Comments

@AudriusButkevicius
Copy link
Contributor

AudriusButkevicius commented Aug 9, 2016

package main

import(
    "fmt"
    "time"
    "net"
    "github.com/AudriusButkevicius/kcp-go"
)

func dial(addr net.Addr) {
    c, err := kcp.Dial(addr.String())
    if err != nil {
        panic(err)
    }
    n, err := c.Write([]byte("hello"))
    if err != nil {
        panic(err)
    }
    b := make([]byte, 10)
    n, err = c.Read(b)
    fmt.Println("DIAL", string(b[:n]), err)
    c.Close()
}

func main() {
    l, err := kcp.Listen("127.0.0.1:0")
    fmt.Println(l.Addr().String())
    caddr := l.Addr()
    if err != nil {
        panic(err)
    }

    b := make([]byte, 10)

    go func() {
        time.Sleep(time.Second)
        dial(caddr)
    }()

    go func() {
        time.Sleep(time.Second*5)
        panic("timeout")
    }()

    for {
        c, err := l.Accept()
        if err != nil {
            panic(err)
        }
        c.Write([]byte("hi"))
        n, err := c.Read(b)
        fmt.Println("LISTEN", string(b[:n]), err)
        c.Close()
    }
}

I'd expect the output to be:

127.0.0.1:60678
LISTEN hello <nil>
DIAL hi <nil>
panic: timeout

Actual output:

127.0.0.1:60678
LISTEN hello <nil>
LISTEN hello <nil>
LISTEN hello <nil>
LISTEN hello <nil>
LISTEN hello <nil>
LISTEN hello <nil>
panic: timeout

I guess it always assumes a new conversation, given .Close() is called on the accept side?

@xtaci
Copy link
Owner

xtaci commented Aug 10, 2016

    for {
        c, err := l.Accept()
        if err != nil {
            panic(err)
        }
        c.Write([]byte("hi"))
        n, err := c.Read(b)
        fmt.Println("LISTEN", string(b[:n]), err)
    time.Sleep(time.Second)   /// this will let listener send data to client
        c.Close()
    }

your output tells that client tries to retransmit hello message, but the listener never had a chance to send data, because it's closed immediately after Read().

KCP doesn't define session control messages like SYN/FIN/RST in TCP, a real world example is to use some multiplexing protocol over session, such as yamux.

@AudriusButkevicius
Copy link
Contributor Author

I am more worried that the dial part keeps trying to send data even after Close(). I fully understand that there is no session control, but TIME_WAIT could be implemented based on the convID on the listen side, essentially ignoring all packets for some time.

Regarding the timeout, not sure why you've pointed at this issue as it's somewhat a different question.
I saw that there was a local var related to connection timeout, but it's not used anywherr.

Are you saying application level timeouts is the right and only way to solve it? Or are you saying yamux solves it?

@xtaci
Copy link
Owner

xtaci commented Aug 10, 2016

application level timeouts is the right and only way to solve it.

@AudriusButkevicius
Copy link
Contributor Author

I see yamux has some tcp like control messages which might help solve this, I'll see where that takes me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants