【问题标题】:Golang TCP server gives "dial tcp 127.0.0.1:9999: connect: connection refused" errorGolang TCP 服务器给出“拨号 tcp 127.0.0.1:9999:连接:连接被拒绝”错误
【发布时间】:2022-05-02 23:13:24
【问题描述】:

我在学习An Introduction to Programming in Go by Caleb Doxsey这本书

In chapter 13 about servers我们得到了代码:

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)
}

运行这段代码我几乎总是收到:

客户端,Dial dial tcp 127.0.0.1:9999:连接:连接被拒绝

但有时我会收到:

发送 Hello World

收到Hello World

我还发现,如果我只运行与客户端分开运行服务器,然后在单独的文件上运行客户端,它会按预期工作。这是为什么呢?

【问题讨论】:

  • 服务器和客户端 goroutine 之间没有协调,客户端在服务器监听之前拨号
  • A server 不会给出连接被拒绝错误。当服务器拒绝连接时,客户端会给出该错误。

标签: go


【解决方案1】:

Listen 和 Dial 是同时调用的,你无法预测哪个先执行。如果 Dial 在 Listen 之前执行,那么显然还没有任何东西在侦听,这会产生错误。

在启动 goroutine 之前在 main 中调用 Listen:

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)
    }
}

【讨论】:

  • 感谢您的解释!
  • 还要无限期阻止,将Scanln替换为单行:select {}
猜你喜欢
  • 2020-01-01
  • 2020-12-31
  • 2021-07-31
  • 1970-01-01
  • 2020-02-21
  • 2019-12-12
  • 2018-12-26
  • 1970-01-01
  • 2019-12-25
相关资源
最近更新 更多