正反向代理 Golang实现 - Go语言中文社区

正反向代理 Golang实现


正向代理隐藏了真实客户端向服务器发送请求,反向代理隐藏了真实服务器向客户端提供服务。

 

正向代理:

小王要结婚了,可是手上拿不出彩礼钱,他就找了好兄弟小张,小张同样没钱,但是小张认识思聪,于是小张从王思聪那里借到了20万交到了小王手上。对于思聪来说,他并不知道真正借钱的人是小王。

常见例子:科学上网VPN

反向代理:

小王结婚买房,他找到贷款中介,贷款中介给了他50万。但中介找哪个资方出资50万,小王完全不知情。

常见例子:Nginx反向代理服务器

 

代理架构图如下所示

 

 

Golang示例代码

server.go


type Server struct {
  listener net.Listener
}

func NewServer(address ...string) []*Server {
  s := make([]*Server, 0)
  for _, a := range address {
    lst, _ := net.Listen("tcp", a)
    s = append(s, &Server{
      listener: lst,
    })
  }
  return s
}

func (s *Server) Run() {
  for {
    conn, _ := s.listener.Accept() //服务器监听代理请求
    go s.handler(conn)
  }
}

func (s *Server) handler(conn net.Conn) {
  for {
    msg := make([]byte, 1024)
    _, _ = conn.Read(msg) //读取代理转发的客户端请求
    fmt.Println(string(msg))
    _, _ = conn.Write([]byte(fmt.Sprintf("message from Server: %s", s.listener.Addr().String()))) //服务器写入内容
  }
}

agent.go

type Proxy struct {
  listener       net.Listener
  backendAddress string
}

func NewProxy(agentAddress, serverAddress string) *Proxy {
  lst, _ := net.Listen("tcp", agentAddress)
  return &Proxy{
    listener:       lst,
    backendAddress: serverAddress,
  }
}

func (p *Proxy) Run() {
  for {
    frontConn, _ := p.listener.Accept() //等待客户端请求
    backendConn, _ := net.Dial("tcp", p.backendAddress)
    go p.Agent(frontConn, backendConn)
  }
}

func (p *Proxy) Agent(frontConn, backendConn net.Conn) { //转发客户端请求与服务器返回
  go io.Copy(backendConn, frontConn)
  go io.Copy(frontConn, backendConn)
}


client.go

type Client struct {
  conn net.Conn
}

func NewClient(proxyAddress string, num int) []*Client {
  c := make([]*Client, 0)
  for i := 0; i < num; i++ {
    conn, _ := net.Dial("tcp", proxyAddress)
    c = append(c, &Client{conn: conn})
  }
  return c
}

func (c *Client) Run() {
  //发起客户端请求
  _, _ = c.conn.Write([]byte(fmt.Sprintf("message from client: %s", c.conn.LocalAddr().String())))
  msg := make([]byte, 1024)
  //读取代理返回内容
  c.conn.Read(msg)
  fmt.Println(string(msg))
}

client.go


type Client struct {
  conn net.Conn
}

func NewClient(proxyAddress string, num int) []*Client {
  c := make([]*Client, 0)
  for i := 0; i < num; i++ {
    conn, _ := net.Dial("tcp", proxyAddress)
    c = append(c, &Client{conn: conn})
  }
  return c
}

func (c *Client) Run() {
  //发起客户端请求
  _, _ = c.conn.Write([]byte(fmt.Sprintf("message from client: %s", c.conn.LocalAddr().String())))
  msg := make([]byte, 1024)
  //读取代理返回内容
  c.conn.Read(msg)
  fmt.Println(string(msg))
}

main.go


func main() {
  servers := server.NewServer(":9998", ":9999") //开启本地9998和9999为服务器端口
  for _, s := range servers {
    go s.Run()
  }

  p := proxy.NewProxy(":9000", ":9999") //代理服务器端口9000,转发服务器端口9999
  go p.Run()

  for _, c := range client.NewClient(":9000", 3) { //客户端向9000代理端口发送请求
    go c.Run()
  }
  select {}

获取完整代码见Github地址:https://github.com/slpslpslp/proxyDemo

想学习更多Go知识,请关注公众号:Golang技术分享。

 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/slphahaha/article/details/106176161
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-06-27 18:07:54
  • 阅读 ( 764 )
  • 分类:Go

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢