Question

I did some experiment on Golang net package.

When I use a client to connect a server (without close connections), I found that server had error like this: "too many open files" It makes sense because the file open limit set in my os.

However, I found that client never returned errors when connecting to server, which is weird since server had already rejected some of connection requests.

// Server code
package main

import (
    "log"
    "net"
)

func main() {
    listener, err := net.Listen("tcp", "localhost:7070")
    if err != nil {
        log.Fatalln(err)
    }
    for {
        conn, err := listener.Accept()
        if err != nil {
            log.Println(err, conn)
            continue
        }
    }
}


// Client code
package main

import (
    "log"
    "net"
)

func main() {
    cnt := 0
    for {
        conn, err := net.Dial("tcp", "localhost:7070")
        if err != nil {
            log.Println("!", conn.RemoteAddr())
            continue
        }
        cnt++
        n, err := conn.Write([]byte("hello"))
        if err != nil {
            log.Fatalln(err)
        }

        log.Println(cnt, n)

    }

}

Can anyone tell me what happens here?

thx.

Was it helpful?

Solution

The TCP handshake is asynchronously performed on the server by the kernel TCP/IP stack before the server application accepts it, so even if your server code fails to accept the connection, it will be connected at the TCP level. That's why the net.Dial() succeeds.

When your server code accept of the connection fails, the TCP/IP stack will close the connection though.

net.Write() just passes data onto the local TCP/IP stack, which will asynchronously send the data. If this is done before the server code has had a chance to (fail to) accept the connection, there's no error as the tcp connection is still operational. If your client perform a 2. write, or perhaps waits a bit, net.Write() should fail too.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top