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