英文:
When the TCP connection close in this code?
问题
当我阅读这个开源代码时,我对这两个函数有两个问题:
-
你可以看到代码中使用了
sync.WaitGroup
,如果它们只发送了left->right
方向的流量,没有相反方向的流量,那么handleTCPConn
函数将不会结束,对吗?如果是这样,那么listenTCP
的循环将创建许多handleTCPConn
函数调用,这个程序没有问题吗? -
每次使用
handleTCPConn
函数时,它都会创建一个到远程服务器的TCP连接。
remoteConn, err := conn.(*tproxy.Conn).DialOriginalDestination(false)
我的问题仍然是关于问题1,你可以看到handleTCPConn
函数在两个方向上传输流量一次,然后结束它,当handleTCPConn
函数结束时,TCP连接是否关闭?如果它们只传输了文件的一部分数据(从应用层的角度来看),连接是否也会关闭?(我的意思是,如果A->B->C传输了部分数据,然后C->B->A发送了ACK)。
英文:
When I read this opensource code.
I have two questions about the two functions:
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()
}
Based on my understanding, I draw this diagram:
You see, the handleTCPConn created two goroutines for transmitting two direction(left -> right; right -> left)'s traffic,
My questions are:
-
You see the code use
sync.WaitGroup
, if they only sendleft-> right
traffic, there is no traffic in opposite direction, so thehandleTCPConn
will not end, right? if it is, thelistenTCP
for loop will create many of thosehandleTCPConn
function calls, is there nothing wrong with this program? -
Every time the
handleTCPConn
is used, it will create a TCP connection to the remote server.
remoteConn, err := conn.(*tproxy.Conn).DialOriginalDestination(false)
My question is still in question 1, you can see that the handleTCPConn
transmit the traffic once in both directions, and then ends it, whether the TCP connection is closed when does handleTCPConn end?
if they only transmit part of the data of a file(as per the application layer view), whether it is closed too? (i mean, if A->B->C: part data , then C->B->A: ACK ) .
答案1
得分: 1
根据golang文档(https://pkg.go.dev/io#Copy)的说明:
Copy函数会从源(src)复制数据到目标(dst),直到源达到EOF(文件末尾)或者发生错误。它会返回复制的字节数以及在复制过程中遇到的第一个错误(如果有的话)。
因此,当你启动这个程序时,它会等待你触发“proxy”,然后将源数据发送到目标位置...当目标位置响应时,它会将所有这些字节复制回来。如果目标位置既不写入任何字节,也不关闭连接,我认为它会一直等待,直到远程端关闭套接字或响应为止。
如果你建立这个连接并且远程端开始发送数据(没有先发送请求),如果“本地”端从不发送任何字节并且不关闭连接,这段代码也会一直等待。
只要远程端正常关闭连接,这段代码应该会以接收到“0”字节且没有错误的方式退出。如果远程端发送复位信号,你应该会收到某种错误。
英文:
per the golang docs, https://pkg.go.dev/io#Copy
> Copy copies from src to dst until either EOF is reached on src or an error occurs. It returns the number of bytes copied and the first error encountered while copying, if any.
So when you start this program up, it will sit there and wait for you to hit the 'proxy', and send your bytes from the source to the destination... when the destination responds it will copy all those bytes back. if the destination doesn't write any bytes and doesn't close the connection i believe it'll sit there forever, waiting for the far side to either close the socket or respond.
Same is true if you make this connection and the remote sides starts sending data (without a request first). If the "local" side never sends any bytes and doesn't close the connection this code would wait forever as well.
As long as the remote side closes the connection gracefully, this code should exit with "0" bytes received and no error. If the remote side sends a reset, you should get an error of some kind
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论