解决 golang 的无缓冲通道会阻塞的问题

2021-05-03 17:10:29 +08:00
 proxytoworld

如题,我需要在建立 TCP 连接之后循环处理来自客户端的连接请求,并接收来自客户端的数据,在客户端第三次发送数据之后断开连接,取消监听,我使用 select 来取消无缓冲通道的阻塞,但是 handleTcpConnection 向通道发送信号后,sendAndReceiveTcpData 没办法接收信号,导致程序卡死在 handleTcpConnection

如果不用 select 则程序会阻塞在 sendAndReceiveTcpData 接收通道的代码处,没办法处理第二个用户请求,求问怎么解决该问题

func sendAndReceiveTcpData(ln net.Listener) {
defer func() {
	helper.Wt.Done()
	log.Println("sendAndReceiveTcpData 返回")
}()
exitSignal := make(chan bool)
log.Println("信号创建")
var clientNumber = 1
for {
	log.Printf("等待第%d 客户端请求\n", clientNumber)
	conn, err := ln.Accept()
	log.Println("接到请求")
	if err != nil {
		log.Fatalf("和客户端连接失败%s\n", err)
	}
	log.Println("和客户端连接成功")
	clientNumber++
	helper.Wt.Add(1)
	go handleTcpConnection(conn, &exitSignal)

	log.Println("handleTcpConnection 协程创建")
	select {
	case <-exitSignal:
		e := <-exitSignal
		log.Println("接到信号")
		if e{
			goto x
		}
	default:
		log.Println("下一轮")
	}
}
x:
	log.Println("结束 senddata for 循环")
}
func handleTcpConnection(conn net.Conn, e *chan bool) bool {
    defer func() {
        helper.Wt.Done()
        log.Print("handleTcpConnection 返回\n")

    }()

    br := bufio.NewReader(conn)
    var counter = 0
    for {
        data, err := br.ReadString('\n')
        if err == io.EOF {
            break
        }
        if counter == 3{
            log.Println("发送信号")
            *e<-true
            break
        }
        log.Printf("客户端 %s => %s", conn.RemoteAddr(), data)
        counter++
    }
    log.Println("结束 handle for 循环")
    return true
}
958 次点击
所在节点    问与答
5 条回复
pabupa
2021-05-03 17:46:07 +08:00
因为`ln.Accept()`是阻塞调用。它会卡到有新连接来的时候才返回。
proxytoworld
2021-05-03 17:58:28 +08:00
@pabupa 刚刚注意到了这个问题,如何解决这种问题?一边等待新的连接,一边监听已有的连接是否发出信号
proxytoworld
2021-05-03 17:59:39 +08:00
同时有两个阻塞调用
AlisaDestiny
2021-05-03 18:23:56 +08:00
专门起一个 goroutine 监听 exitSignal,接收到信号就调用 Listener 的 Close 方法。
proxytoworld
2021-05-03 21:47:04 +08:00
@AlisaDestiny 有道理

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/774752

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX