sctp icon indicating copy to clipboard operation
sctp copied to clipboard

Non-blocking SCTP Socket

Open calee0219 opened this issue 5 years ago • 6 comments

I have test the code like following: In short it's just goroutine the accept and close the listener. In TCP test, accept will return error and we can use error handling to close the socket. But in SCTP, the accept will not return error and keep binding on the fd. Therefor, we cannot reuse the address.

After I take a look of TCP's implementation, I found that TCP is using non-blocking flag in syscall. Due to the reason, accept won't block the fd in system and can successfully return the error when listener close.

Is it possible to change the architecture of SCTP to non-blocking socket type?

package main

import (
        "fmt"
        "net"
        "time"

        "github.com/ishidawataru/sctp"
)

func main() {
        port := 38412
        ips := []net.IPAddr{}
        a, err := net.ResolveIPAddr("ip", "127.0.0.1")
        if err != nil {
                fmt.Print("err")
        }
        ips = append(ips, *a)

        addr := &sctp.SCTPAddr{
                IPAddrs: ips,
                Port:    port,
        }

        ln, err := sctp.ListenSCTP("sctp", addr)
        if err != nil {
                fmt.Print("err")
        }
        fmt.Println("Start listen")

        go func() {
                for {
                        sctpConn, err := ln.AcceptSCTP()
                        if err != nil {
                                fmt.Printf("err: %d\n", err)
                                return
                        }
                        defer sctpConn.Close()
                        fmt.Println("Accept from: ", sctpConn.RemoteAddr().String())
                        buffer := make([]byte, 8192)
                        n, _, err := sctpConn.SCTPRead(buffer)
                        fmt.Println(buffer[:n])
                        sctpConn.Close()
                }
        }()

        time.Sleep(10 * time.Second)

        ln.Close()
        fmt.Println("close socket")

        time.Sleep(50 * time.Second)
}

calee0219 avatar Dec 29 '19 19:12 calee0219