首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TCP接受和转发并发模型

TCP接受和转发并发模型
EN

Stack Overflow用户
提问于 2015-04-29 15:40:45
回答 1查看 7.4K关注 0票数 6

看着net.TCPListener。考虑到Go并发模式,人们会期望将这个系统功能作为一个通道来实现,这样您就可以从一个chan *net.Conn函数中得到一个Listen(),或者类似的东西。

但它似乎是接受()的方式,而这只是块,就像系统接受。只是它残废了,因为:

  • 没有适当的select()可以与它一起使用,因为go更喜欢频道
  • 无法为服务器套接字设置阻塞选项。

所以我要做的事情是:

代码语言:javascript
复制
    acceptChannel = make(chan *Connection)
    go func() {
      for {
       rw, err := listener.Accept()
       if err != nil { ... handle error ... close(acceptChannel) ... return }
       s.acceptChannel <-&Connection{tcpConn: rw, .... }
      }
    }()

这样,我就可以在select中使用多个服务器套接字,或者与其他通道一起使用对Accept()的等待。我是不是遗漏了什么?我是新来的,所以我可能忽略了一些事情--但真的没有用自己的并发模式实现自己的阻塞系统功能吗?我真的需要为我想要听的每一个插座(可能是几百或数千个)建立一个单独的大猩猩吗?这是正确的成语使用,还是有更好的方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-29 16:02:09

你的代码很好。您甚至可以更进一步地替换:

代码语言:javascript
复制
s.acceptChannel <-&Connection{tcpConn: rw, .... }

通过以下方式:

代码语言:javascript
复制
go handleConnection(&Connection{tcpConn: rw, .... })

正如注释中提到的,例程不是系统线程,它们是由Go运行时管理的轻量级线程。当您为每个连接创建一个例程时,您可以很容易地使用阻塞操作,这些操作更容易实现。Go运行时然后为您选择例程,所以您要寻找的行为只是在其他地方,隐藏在语言中。你看不见,但到处都是。

现在,如果您需要一些更复杂的东西,并且根据我们的对话,实现类似于select的超时,那么您将完全按照您的建议:将所有新连接推送到一个通道,并使用一个计时器对其进行多路复用。这似乎是进去的路。

请注意,如果你们中的一个接受者失败了,你不能关闭接收通道,因为另一个接受者在写信给它时会感到恐慌。

我的(更全面的)例子:

代码语言:javascript
复制
newConns := make(chan net.Conn)

// For every listener spawn the following routine
go func(l net.Listener) {
    for {
        c, err := l.Accept()
        if err != nil {
            // handle error (and then for example indicate acceptor is down)
            newConns <- nil
            return
        }
        newConns <- c
    }
}(listener)

for {
    select {
    case c := <-newConns:
        // new connection or nil if acceptor is down, in which case we should
        // do something (respawn, stop when everyone is down or just explode)
    case <-time.After(time.Minute):
        // timeout branch, no connection for a minute
    }
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29948497

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档