网站换皮肤了
golang tcp 动态代理转发
时间:2018-05-14 12:45 浏览:1169

摘要

none

利用数据库存储路由表,然后每次建立连接的时候,客户端发送一个id,代理将根据id查找对应的路由,从而实现动态代理。

package main
import (
 "fmt"
 "net"
 "regexp"
 "strconv"
 _ "github.com/go-sql-driver/mysql"
 "github.com/go-xorm/xorm"
 log "github.com/golang/glog"
)
var (
 bufsize int = 10240
 engine  *xorm.Engine
)
func init() {
 //创建数据库连接
 var err error
 fmt.Println("init MySQL")
 //测试修改成自己实际使用的数据库uri
 engine, err = xorm.NewEngine("mysql", `user:passwd@tcp(127.0.0.1:3306)/platformdb?charset=utf8`)
 if err != nil {
 log.Fatalln(err.Error())
 }
 engine.SetMaxIdleConns(50) //设置最大空闲连接数
 engine.SetMaxConns(500)    //设置最大连接数
 engine.ShowDebug = true    //调试
}
func main() {
 ip := "0.0.0.0"
 port := 9198
 Service(ip, port)
}
func Service(ip string, port int) {
 // , dstaddr string, dsthost string
 listen, err := net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP(ip), port, ""})
 if err != nil {
 fmt.Println("listen error: ", err.Error())
 return
 }
 fmt.Println("init done...")
 for {
 client, err := listen.AcceptTCP()
 if err != nil {
 fmt.Println("accept error: ", err.Error())
 continue
 }
 go func() {
 //动态代理
 for {
 buf := make([]byte, bufsize)
 n, err := client.Read(buf)
 if err != nil {
 //调试
 fmt.Printf("ReadRequest断开连接:%s\n", err.Error())
 client.Close()
 break
 }
 if len(buf) != 0 {
 fmt.Println(string(buf[:n]))
 id_str := string(buf[:n])
 id, _ := strconv.Atoi(id_str)
 // time.Sleep(5 * time.Second)
 result, err := engine.Query("SELECT roomvirtualip,port FROM connectroute WHERE id=?", id)
 if err != nil || len(result) == 0 {
 fmt.Println("access MySQL error:", err, len(result))
 continue
 }
 dstaddr := fmt.Sprintf("%s:%s", string(result[0]["virtualip"]), string(result[0]["port"]))
 dsthost := "Host: " + dstaddr
 //调试
 fmt.Printf("建立连接:client=%s server=%s\n", client.RemoteAddr().String(), dstaddr)
 go Channal(client, dstaddr, dsthost)
 break
 }
 }
 }()
 }
}
func Channal(client *net.TCPConn, addr string, rhost string) {
 tcpAddr, _ := net.ResolveTCPAddr("tcp4", addr)
 conn, err := net.DialTCP("tcp", nil, tcpAddr)
 if err != nil {
 fmt.Println("connection error: ", err.Error())
 client.Close()
 return
 }
 //客户端与服务端打通
 go ReadRequest(client, conn, rhost)
 go ReadResponse(conn, client)
}
//请求
func ReadRequest(lconn *net.TCPConn, rconn *net.TCPConn, dsthost string) {
 //调试
 fmt.Printf("请求:%s->%s->%s->%s\n", lconn.RemoteAddr().String(), lconn.LocalAddr().String(), rconn.LocalAddr().String(), rconn.RemoteAddr().String())
 for {
 buf := make([]byte, bufsize)
 n, err := lconn.Read(buf)
 if err != nil {
 //调试
 fmt.Printf("ReadRequest断开连接:%s\n", err.Error())
 break
 }
 mesg := changeHost(string(buf[:n]), dsthost)
 //print request
 // fmt.Println(mesg)
 rconn.Write([]byte(mesg))
 }
 lconn.Close()
 rconn.Close()
}
//响应
func ReadResponse(lconn *net.TCPConn, rconn *net.TCPConn) {
 //调试
 fmt.Printf("响应:%s->%s->%s->%s\n", lconn.RemoteAddr().String(), lconn.LocalAddr().String(), rconn.LocalAddr().String(), rconn.RemoteAddr().String())
 for {
 buf := make([]byte, bufsize)
 n, err := lconn.Read(buf)
 if err != nil {
 //调试
 fmt.Printf("ReadResponse断开连接:%s\n", err.Error())
 break
 }
 // fmt.Println(string(buf[:n]))
 rconn.Write(buf[:n])
 }
 lconn.Close()
 rconn.Close()
}
func changeHost(request string, newhost string) string {
 reg := regexp.MustCompile(`Host[^\r\n]+`)
 return reg.ReplaceAllString(request, newhost)
}

             



如果这篇文章对你有所帮助,可以通过下边的“打赏”功能进行小额的打赏。

本网站部分内容来源于互联网,如有侵犯版权请来信告知,我们将立即处理。


来说两句吧