这个无限循环在TCP连接中是如何工作的?

huangapple go评论83阅读模式
英文:

How this infinite for loop works in TCP connection?

问题

这个无限循环的代码为什么不会崩溃呢?

我原以为如果此刻没有客户端连接,listener.Accept() 方法会抛出一个错误,使得 if 条件为真,从而使得 for 循环继续到下一次迭代,直到有客户端连接到服务器。因此,我在 if 语句中加入了 fmt.Println("Error") 来查看是否按照我猜测的方式工作。但是它并没有打印出 "Error",所以当没有客户端连接时,程序并没有进入 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
        }
    }
}
英文:

How this infinite for loop is not crashing?

I thought if there were no clients right now, listener.Accept() method were throwing an error which makes the if condition true and the for loop continues to the other iteration until the client connects to a server. Therefore I put fmt.Println("Error") in the if statement to see if it was working as I guessed. But it wasn't. It did not print "Error" so the program is not going into the if statement when there were no clients.

Can someone explain how this for loop actually works?

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
            }
            
            
        }
    } 

答案1

得分: 2

这个无限循环做了以下几件事情:

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

  2. 如果返回值存在,检查是否有错误。如果有错误,记录下来或者进行其他处理,然后继续循环,这样服务器可以等待新的连接。

  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)
    }
}
英文:

This infinite loop is do the followings:

  1. Wait for the listener.Accept() to return either with a new connection or an error.

  2. If you got a return value, check for the error. If you have one, log it, or do anything with it, then continue the loop, so the server can wait for another new connection.

  3. If you don't have an error, simply start a separate go routine which can handle the connection. This way the for loop immediately runs again, so the listener will wait for a new connection while you handle the connection in a separate routine.

See the example:

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)
    }
} 

huangapple
  • 本文由 发表于 2021年8月6日 01:16:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/68670933.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定