为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
森林海 2022-10-24 10:17:14
我正在尝试为基于CONNECT的 HTTP 代理创建反向代理。想要使用代理的用户只是将machine A其视为 HTTP 代理。它的工作方式如下:machine B打开一个 TCP 套接字到machine A.在 上machine A,TCP 套接字在端口上公开,所有传入数据都通过隧道传输到machine B(io.Copy)。开启machine B时,所有数据都通过隧道传输到本地 HTTP 服务器和套接字machine A。本质上,这是 HTTP 代理背后的反向代理。之所以如此复杂,是因为 HTTP 代理位于 NAT 之后(打开machine B),因此无法直接访问。该用例能够在 NAT 后面托管 HTTP 代理。机器A隧道(Go):package mainimport (    "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())
查看完整描述

1 回答

?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

当你这样做


go func() {

    for {

        donorConn, err := listenerDonors.AcceptTCP()

        donorConn.SetKeepAlive(true)

        if err != nil {

            utils.StacktraceErrorAndExit(err)

            return

        }

        log.Println("New donor connection from", Conn(donorConn))

        donorConns <- donorConn

    }

}()

您开始处理第一个 TCP 连接。此代码块在donorConns <- donorConn. 在此发送到通道完成之前,循环不会进入第二次迭代(并且不会接受下一个 TCP 连接)。


你做了一个非常相似的第二个循环


// Handle recipient connections

for {

    recipientConn, err := listenerRecipients.AcceptTCP()

    recipientConn.SetKeepAlive(true)

    if err != nil {

        utils.StacktraceErrorAndExit(err)

        return

    }

    log.Println("New recipient connection from", Conn(recipientConn))

    donorConn := <-donorConns

    proxy.ProxifyConns(recipientConn, donorConn)

}

这需要donorConn := <-donorConns完成(从第一个循环开始)并且需要proxy.ProxifyConns(recipientConn, donorConn)完成。


我不确定你打算如何让整个工作,但是,很可能,你需要一个很小的改变:

go proxy.ProxifyConns(recipientConn, donorConn)


查看完整回答
反对 回复 2022-10-24
  • 1 回答
  • 0 关注
  • 191 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号