使反向 TCP 连接接受任意数量的连接(如普通 TCP 服务器)

我正在尝试为基于CONNECT的 HTTP 代理创建反向代理。想要使用代理的用户只是将machine A其视为 HTTP 代理。它的工作方式如下:

  1. machine B打开一个 TCP 套接字到machine A.

  2. 在 上machine A,TCP 套接字在端口上公开,所有传入数据都通过隧道传输到machine B(io.Copy)。

  3. 开启machine B时,所有数据都通过隧道传输到本地 HTTP 服务器和套接字machine A

本质上,这是 HTTP 代理背后的反向代理。之所以如此复杂,是因为 HTTP 代理位于 NAT 之后(打开machine B),因此无法直接访问。该用例能够在 NAT 后面托管 HTTP 代理。

机器A隧道(Go):

package main


import (

    "log"

    "net"

)


func Conn(c *net.TCPConn) string {

    return c.RemoteAddr().String() + " (" + c.LocalAddr().String() + ")"

}


func ProxifyConns(recipientConn, donorConn *net.TCPConn) {

    log.Println("Proxying", ConnrecipientConn), "and", Conn(donorConn))

    go func() {

        _, err := io.Copy(recipientConn, donorConn)

        if err != nil {

            utils.StacktraceError(err)

        }

        recipientConn.Close()

    }()

    go func() {

        _, err := io.Copy(donorConn, recipientConn)

        if err != nil {

            utils.StacktraceError(err)

        }

        recipientConn.Close()

    }()

}



func main() {

    // Open the donor listener

    donorsAddr, err := net.ResolveTCPAddr("tcp4", ":11000")

    if err != nil {

        utils.StacktraceErrorAndExit(err)

    }

    listenerDonors, err := net.ListenTCP("tcp", donorsAddr)

    if err != nil {

        utils.StacktraceErrorAndExit(err)

    }

    defer listenerDonors.Close()

    log.Println("Listening for donors on", listenerDonors.Addr())


    // Open the recipient listener

    recipientsAddr, err := net.ResolveTCPAddr("tcp4", ":10000")

    if err != nil {

        utils.StacktraceErrorAndExit(err)

    }

    listenerRecipients, err := net.ListenTCP("tcp", recipientsAddr)

    if err != nil {

        utils.StacktraceErrorAndExit(err)

    }

    defer listenerRecipients.Close()

    log.Println("Listening for recipients on", listenerRecipients.Addr())



森林海
浏览 193回答 1
1回答

天涯尽头无女友

当你这样做go func() {&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; donorConn, err := listenerDonors.AcceptTCP()&nbsp; &nbsp; &nbsp; &nbsp; donorConn.SetKeepAlive(true)&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; utils.StacktraceErrorAndExit(err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; log.Println("New donor connection from", Conn(donorConn))&nbsp; &nbsp; &nbsp; &nbsp; donorConns <- donorConn&nbsp; &nbsp; }}()您开始处理第一个 TCP 连接。此代码块在donorConns <- donorConn. 在此发送到通道完成之前,循环不会进入第二次迭代(并且不会接受下一个 TCP 连接)。你做了一个非常相似的第二个循环// Handle recipient connectionsfor {&nbsp; &nbsp; recipientConn, err := listenerRecipients.AcceptTCP()&nbsp; &nbsp; recipientConn.SetKeepAlive(true)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; utils.StacktraceErrorAndExit(err)&nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; }&nbsp; &nbsp; log.Println("New recipient connection from", Conn(recipientConn))&nbsp; &nbsp; donorConn := <-donorConns&nbsp; &nbsp; proxy.ProxifyConns(recipientConn, donorConn)}这需要donorConn := <-donorConns完成(从第一个循环开始)并且需要proxy.ProxifyConns(recipientConn, donorConn)完成。我不确定你打算如何让整个工作,但是,很可能,你需要一个很小的改变:go proxy.ProxifyConns(recipientConn, donorConn)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go