Go 新的TCP连接抛出“使用封闭的网络连接”,即使它刚刚被打开

Go 新的TCP连接抛出“使用封闭的网络连接”,即使它刚刚被打开,go,tcp,Go,Tcp,打开新连接时,有时会在receive函数中的client.Socket.Readmessage处出现闭合网络连接错误 这已经够奇怪了,但真正奇怪的是,当客户端通过manager.unregister时,我在closeconnection.Data尝试关闭一个封闭通道时出错 我在这里显然遗漏了一些东西,因为我所有的日志都表明这些是全新的、未使用的通道和套接字 有什么想法吗 我使用的是Golang版本1.10 type ClientManager struct { clients map[*

打开新连接时,有时会在receive函数中的client.Socket.Readmessage处出现闭合网络连接错误

这已经够奇怪了,但真正奇怪的是,当客户端通过manager.unregister时,我在closeconnection.Data尝试关闭一个封闭通道时出错

我在这里显然遗漏了一些东西,因为我所有的日志都表明这些是全新的、未使用的通道和套接字

有什么想法吗

我使用的是Golang版本1.10

type ClientManager struct {
    clients map[*types.Client]bool
    broadcast chan []byte
    register chan *types.Client
    unregister chan *types.Client
}

func CloseSocket(client *types.Client) {
    client.M.Lock()
    defer client.M.Unlock()

    if !client.Closed {
        client.Socket.Close()
        client.Closed = true
    }
}

func (manager *ClientManager) receive(client *types.Client) {
    for {
            message := make([]byte, 4096)
            fmt.Println("client listening:", client)
            length, err := client.Socket.Read(message)

            if err != nil {
                    fmt.Println(err)
                    manager.unregister <- client
                    CloseSocket(client)
                    break
            }
            if length > 0 {
                    request := util.DecodeGob(message)
                    HandleRequest(request, client)
            }
    }
}

func (manager *ClientManager) start() {
    fmt.Println("Listening for TCP connections...")
    for {
            select {
            case connection := <-manager.register:
                    manager.clients[connection] = true
                    fmt.Println("Added new connection!")
            case connection := <-manager.unregister:
                    if _, ok := manager.clients[connection]; ok {
                            close(connection.Data)
                            delete(manager.clients, connection)
                            fmt.Println("manager.clients:", manager.clients)
                            fmt.Println("A connection has terminated!")
                    }
    }
}

func Run(port string) {
    fmt.Println("Starting server...")

    listener, error := net.Listen("tcp", port)

    if error != nil {
            fmt.Println(error)
    }

    manager := ClientManager{
            clients: make(map[*types.Client]bool),
            broadcast: make(chan []byte),
            register: make(chan *types.Client),
            unregister: make(chan *types.Client),
    }

    go manager.start()

    fmt.Println("Server running on port " + port + "!")

    for {
            connection, _ := listener.Accept()
            if error != nil {
                    fmt.Println(error)
            }

            fmt.Println("\nRemote address:", connection.RemoteAddr())

            client := &types.Client{Socket: connection, Data: make(chan []byte)}

            manager.register <- client
            go manager.receive(client)
            go manager.send(client)
    }
}

编辑:将互斥添加到客户端,不再有竞争输出。错误仍然存在。

好的,解决了。我需要为第一次写入通道实现回退,因为有时第一次写入失败。现在它优雅地等待片刻,并完美地连接起来。下面是它的样子:

func SendBackoff(data []byte, client *types.Client, i int) {
    select {
    case client.Data <- data:
        return
    default:
        time.Sleep(500 * time.Millisecond)

        fmt.Println("Trying again!", i)
        if (i > 5) {
            return
        }
        SendBackoff(data, client, i + 1)
    }
}

func SendToClient(request types.Request, client *types.Client) {
    data, err := util.GobToBytes(request)

    if err != nil {
            fmt.Println(err)
            return
    }

    fmt.Println("Trying to send:", data)

    SendBackoff(data, client, 1)
}
使用运行应用程序并修复所有问题。显示写入连接的代码。死机:关闭关闭通道意味着程序逻辑存在根本性问题,您需要首先修复该问题,这可能还包括使用关闭的网络连接。您还需要正确读取连接-在处理错误之前始终处理读取的字节;见
func SendBackoff(data []byte, client *types.Client, i int) {
    select {
    case client.Data <- data:
        return
    default:
        time.Sleep(500 * time.Millisecond)

        fmt.Println("Trying again!", i)
        if (i > 5) {
            return
        }
        SendBackoff(data, client, i + 1)
    }
}

func SendToClient(request types.Request, client *types.Client) {
    data, err := util.GobToBytes(request)

    if err != nil {
            fmt.Println(err)
            return
    }

    fmt.Println("Trying to send:", data)

    SendBackoff(data, client, 1)
}