Skip to content

TCPConn.Close() does not close the port leaving it in TIME_WAIT status #32961

@dpensi

Description

@dpensi

What version of Go are you using (go version)?

$ go version
go version go1.12.6 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

 
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/daniele/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/daniele/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build361582700=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I had this file: main.go:

package main

import (
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"os"
	"time"
)

func main() {

	mode := flag.String("mode", "", "[client|server]")
	flag.Parse()

	if *mode == "server" {
		go runServer()
		for {
			time.Sleep(2 * time.Second)
		}
	} else if *mode == "client" {
		runClient()
	} else {
		log.Fatal(errors.New("wrong command line parameter"))
		os.Exit(1)
	}
}

func runServer() {

	listener, err := net.Listen("tcp", ":12000")

	if err != nil {
		log.Fatal(err)
	}

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Fatal(err)
		}
		go handleConnection(conn)
	}
}

func runClient() {

	LocalAddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:12001")
	RemoteEP := net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 12000}
	conn, err := net.DialTCP("tcp", LocalAddr, &RemoteEP)

	if err != nil {
		log.Fatal(err)
	}

	fmt.Fprintf(conn, "hi, I'm a client\n")
	conn.CloseWrite()

	b, err := ioutil.ReadAll(conn)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(b))

	conn.Close()
}

func handleConnection(connection net.Conn) {

	b, err := ioutil.ReadAll(connection)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("received: ", string(b))
	fmt.Fprintf(connection, "hi, welcome!\n")

	connection.Close()
}

i run those three commands

$go run main.go -mode server
$go run main.go -mode client
$netstat -an | grep 12000

What did you expect to see?

i expect the output of the netstat command to be:

tcp6 0 0 :::12000 :::* LISTEN

What did you see instead?

tcp        0      0 127.0.0.1:12001         127.0.0.1:12000         TIME_WAIT  
tcp6       0      0 :::12000                :::*                    LISTEN 

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions