这段代码中的 TCP 连接何时关闭?

当我阅读这个开源代码时。

我对这两个功能有两个问题:

func listenTCP() {

    for {

        conn, err := tcpListener.Accept()

        if err != nil {

            if netErr, ok := err.(net.Error); ok && netErr.Temporary() {

                log.Printf("Temporary error while accepting connection: %s", netErr)

            }


            log.Fatalf("Unrecoverable error while accepting connection: %s", err)

            return

        }


        go handleTCPConn(conn)  // check below

    }

}



func handleTCPConn(conn net.Conn) {

    log.Printf("Accepting TCP connection from %s with destination of %s", conn.RemoteAddr().String(), conn.LocalAddr().String())

    defer conn.Close()

    

    remoteConn, err := conn.(*tproxy.Conn).DialOriginalDestination(false)

    if err != nil {

        log.Printf("Failed to connect to original destination [%s]: %s", conn.LocalAddr().String(), err)

        return

    } 

    defer remoteConn.Close()


    var streamWait sync.WaitGroup

    streamWait.Add(2)


    streamConn := func(dst io.Writer, src io.Reader) {

        io.Copy(dst, src)

        streamWait.Done()

    }


    go streamConn(remoteConn, conn)

    go streamConn(conn, remoteConn)


    streamWait.Wait()

}

根据我的理解,我画了这张图:

http://img4.mukewang.com/638dabac0001509313090445.jpg

你看,handleTCPConn 创建了两个 goroutines 来传输两个方向(左 -> 右;右 -> 左)的流量,

我的问题是:

  1. 你看代码使用sync.WaitGroup,如果他们只发送left-> right流量,没有相反方向的流量,那么handleTCPConn不会结束,对吧?如果是这样,listenTCPfor 循环将创建许多这样的handleTCPConn函数调用,这个程序没有问题吗?

  2. 每次handleTCPConn使用时,它都会创建到远程服务器的 TCP 连接。

remoteConn, err := conn.(*tproxy.Conn).DialOriginalDestination(false)

我的问题还是问题1,你可以看到handleTCPConn双向传输一次流量,然后结束,handleTCPConn结束时TCP连接是否关闭?如果他们只传输文件的部分数据(从应用层来看),它是否也被关闭了?(我的意思是,如果 A->B->C: part data ,则 C->B->A: ACK )。


慕容森
浏览 90回答 1
1回答

www说

根据 golang 文档,https: //pkg.go.dev/io#Copy将副本从 src 复制到 dst,直到在 src 上到达 EOF 或发生错误。它返回复制的字节数和复制时遇到的第一个错误(如果有)。所以当你启动这个程序时,它会坐在那里等待你点击“代理”,并将你的字节从源发送到目的地......当目的地响应时它会复制所有这些字节。如果目的地不写入任何字节并且不关闭连接,我相信它会永远坐在那里,等待远端关闭套接字或响应。如果您建立此连接并且远程端开始发送数据(首先没有请求),情况也是如此。如果“本地”端从不发送任何字节并且不关闭连接,则此代码也将永远等待。只要远程端优雅地关闭连接,这段代码就应该在收到“0”字节并且没有错误的情况下退出。如果远端发送重置,你应该得到某种错误
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go