'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?
Solution 1:[1]
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)
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Peter |