简体   繁体   中英

Golang TCP server gives “dial tcp 127.0.0.1:9999: connect: connection refused” error

I am learning from the book An Introduction to Programming in Go by Caleb Doxsey

In chapter 13 about servers we are given the code:

package main

import (
    "encoding/gob"
    "fmt"
    "net"
)

func server() {
    // listen on a port

    ln, err := net.Listen("tcp", ":9999")

    if err != nil {
        fmt.Println("server, Listen", err)
        return
    }

    for {
        // accept a connection
        c, err := ln.Accept()
        if err != nil {
            fmt.Println("server, Accept", err)
            continue
        }
        // handle the connection
        go handleServerConnection(c)
    }
}

func handleServerConnection(c net.Conn) {
    // receive the message
    var msg string
    err := gob.NewDecoder(c).Decode(&msg)
    if err != nil {
        fmt.Println("handleServerConnection", err)
    } else {
        fmt.Println("Received", msg)
    }

    c.Close()
}

func client() {
    // connect to the server
    c, err := net.Dial("tcp", "127.0.0.1:9999")
    if err != nil {
        fmt.Println("client, Dial", err)
        return
    }

    // send the message
    msg := "Hello World"
    fmt.Println("Sending", msg)
    err = gob.NewEncoder(c).Encode(msg)
    if err != nil {
        fmt.Println("client, NewEncoder", err)
    }

    c.Close()
}

func main() {
    go server()
    go client()
    
    var input string
    fmt.Scanln(&input)
}

Running this code i almost always receive:

client, Dial dial tcp 127.0.0.1:9999: connect: connection refused

But sometimes I receive:

Sending Hello World

Received Hello World

I have also discovered if i run just run server separately from client, and then run client on a separate file, it works as intended. Why is that?

Listen and Dial are called concurrently, and you can't predict which one executes first. If Dial executes before Listen then there is obviously nothing listening yet and that produces the error.

Call Listen in main, before starting the goroutines:

func main() {
    ln, err := net.Listen("tcp", ":9999")
    if err != nil {
        fmt.Fatal("server, Listen", err)
    }

    go server(ln)
    go client()
    
    var input string
    fmt.Scanln(&input)
}

func server(ln net.Listener) {
    for {
        // accept a connection
        c, err := ln.Accept()
        if err != nil {
            fmt.Println("server, Accept", err)
            continue
        }
        // handle the connection
        go handleServerConnection(c)
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM