gpt4 book ai didi

golang 聊天服务器/选择语句

转载 作者:IT王子 更新时间:2023-10-29 02:02:07 26 4
gpt4 key购买 nike

我有以下代码实现了一个用 go 编写的简单 tcp 聊天服务器。我无法理解代码中通过“合作伙伴 channel ”发送连接的位置。我看到当第一个用户连接时,select 语句只是等待下一个用户加入。但是当第二个用户加入时,代码如何通过 channel 发送信息并知道选择哪种情况呢?

package main

import (
"io"
"net"
"log"
"fmt"
)
const listnAddr = "localhost:4000"

func main(){
l , err := net.Listen("tcp",listnAddr)
if err != nil {
log.Fatal(err)
}
for {
c , err := l.Accept()
if c!= nil{
fmt.Printf("ok")
}
if err != nil {
log.Fatal(err)
}
go match(c)
}
}
var partner = make(chan io.ReadWriteCloser)

func match(c io.ReadWriteCloser){
fmt.Fprint(c,"waiting for a partner...")
select{
case partner <- c:
//now handled by the other goroutine
case p := <-partner:
chat(p,c)
}
fmt.Printf("waiting")

}

func chat(a, b io.ReadWriteCloser) {
fmt.Fprintln(a, "Found one! Say hi.")
fmt.Fprintln(b, "Found one! Say hi.")
go io.Copy(a, b)
io.Copy(b, a)
}

最佳答案

var partner = make(chan io.ReadWriteCloser)

func match(c io.ReadWriteCloser) {
fmt.Fprint(c, "waiting for a partner...")
select {
case partner <- c:
//now handled by the other goroutine
case p := <-partner:
chat(p, c)
}
fmt.Printf("waiting")
}

每次客户端连接时,匹配函数都会被调用一次。我相信这很清楚。

select 语句的第一个案例想要将 TCP 连接发送到伙伴 channel 。第二种情况想要从合作伙伴 channel 接收 TCP 连接。

如果一个 select 语句的多个 case 准备好继续,the runtime picks one at random .

当第一次调用 match 时(我们称之为 M1),两种情况都无法继续,因为 channel 是无缓冲的; M1 阻塞并等待。第二次(M2)调用match时,实际上无法预测接下来会发生什么,但效果是一样的。

假设 M2 尝试处理第一种情况,将第二个连接发送给合作伙伴。这将起作用,因为 M1 已准备好接收它。所以 M2 继续处理第一种情况,M1 继续处理第二种情况并调用 chat

现在让我们回过头来假设 M2 尝试继续第二种情况,从合作伙伴那里接收另一个连接。这也有效,因为 M1 已准备好发送第一个连接。所以在这种情况下,M1 继续处理第一种情况,M2 继续处理第二种情况并调用 chat

所以 chat 在这两种情况下都会被调用,但参数的顺序是不确定的。在这种情况下,无论哪种方式都有效,因为通信是双向的,我们不关心谁先来。

然后一切又重新开始。

关于golang 聊天服务器/选择语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49784085/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com