【问题标题】:How this infinite for loop works in TCP connection?这个无限循环在 TCP 连接中是如何工作的?
【发布时间】:2021-10-10 17:16:06
【问题描述】:

这个无限的for循环如何不崩溃?

我想如果现在没有客户端,listener.Accept() 方法会抛出一个错误,这使得 if 条件为真,for 循环继续进行另一个迭代,直到客户端连接到服务器。因此,我将fmt.Println("Error") 放在 if 语句中,看看它是否像我猜测的那样工作。但事实并非如此。它没有打印“错误”,因此当没有客户端时,程序不会进入 if 语句。

有人能解释一下这个 for 循环是如何工作的吗?

func main() {
    
        service := ":1202"
        tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
        checkError(err)
    
        listener, err := net.ListenTCP("tcp4", tcpAddr)
        checkError(err)
    
        for {
            conn, err := listener.Accept()
            if err != nil {
                fmt.Println("Error")
                continue
            }
            
            
        }
    } 

【问题讨论】:

  • 你看listener.Accept()做了什么吗?
  • 在文档中,它说“接受等待并将下一个连接返回给侦听器”,所以在有客户端之前它永远不会被调用?
  • 接受将等到客户端连接。
  • 在有客户端之前,它永远不会返回,(或发生一些错误)。
  • 如果你连接得足够多,你要么吃掉你所有的内存,要么吃掉你所有的文件描述符。

标签: go tcp infinite-loop


【解决方案1】:

这个无限循环执行以下操作:

  1. 等待listener.Accept() 返回新连接或错误。

  2. 如果您有返回值,请检查错误。如果你有一个,记录它,或者用它做任何事情,然后continue循环,这样服务器就可以等待另一个新的连接。

  3. 如果您没有错误,只需启动一个单独的 go 例程来处理连接。这样,for 循环会立即再次运行,因此当您在单独的例程中处理连接时,侦听器将等待新连接。

看例子:

func main() {

    service := ":1202"
    tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
    checkError(err)

    listener, err := net.ListenTCP("tcp4", tcpAddr)
    checkError(err)

    for {
        conn, err := listener.Accept()
        if err != nil {
            log.Println("We've got an error:",err)
            continue
        }
        go HandleConnection(conn)
    }
} 

【讨论】:

    猜你喜欢
    • 2015-02-03
    • 2017-09-24
    • 1970-01-01
    • 2015-12-27
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多