You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang TCP程序协程启动时频繁报connection refused错误原因咨询

Why does my Go server-client code fail with "connection refused" when run in the same process but works separately?

这是一个典型的goroutine调度竞态条件问题,我来给你拆解清楚:

当你在main函数里同时启动server()和client()两个goroutine时,Go的调度器并不会保证哪个goroutine先执行。绝大多数情况下,client()会抢先尝试发起连接,而此时server()可能还没完成net.Listen()的初始化流程,端口9999还处于未被监听的状态,自然就会抛出connection refused错误。偶尔成功的情况只是刚好调度器让server()先完成了监听准备,属于小概率的巧合。

而把server和client分开在不同文件运行时,你是手动先启动server,等它完全就绪后再启动client,从根源上避免了竞态问题,所以每次都能正常工作。

解决方法

我们可以通过同步机制确保server完成监听后,client再发起连接,这里用sync.WaitGroup是最直接的方案:

修改后的代码示例:

package main

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

var wg sync.WaitGroup

func server() {
	// listen on a port
	ln, err := net.Listen("tcp", ":9999")
	if err != nil {
		fmt.Println("server, Listen", err)
		wg.Done() // 即使启动失败也标记完成,避免死等
		return
	}
	fmt.Println("Server is ready to accept connections")
	wg.Done() // 通知client可以发起连接了

	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() {
	wg.Wait() // 等待server完成监听准备
	// 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() {
	wg.Add(1)
	go server()
	go client()
	var input string
	fmt.Scanln(&input)
}

其他可选方案

  • 在client中添加重试逻辑:如果连接失败,间隔一段时间后重试几次,直到成功或超时。
  • 使用通道同步:用一个chan struct{}来传递server就绪的信号,效果和WaitGroup类似。

核心思路都是消除两个goroutine之间的竞态,确保server处于就绪状态后,client再尝试连接。

内容的提问来源于stack exchange,提问作者Lame Fanello

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 07:02:35