diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..919933f --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.idea +/.DS_Store +go_build_mysql_proxymain_go \ No newline at end of file diff --git a/lib/packet.go b/lib/packet.go index a982f87..90115e7 100644 --- a/lib/packet.go +++ b/lib/packet.go @@ -16,8 +16,10 @@ func (p Packet) Size() int { return int(uint32(head[0]) | uint32(head[1])<<8 | uint32(head[2])<<16) } -func (p Packet) Id() byte { - return p.raw[3] +// 也就是 Length Coded Binary,其数据长度不固定,长度值由数据前的 1-9 个字节决定,其中长度值所占的字节数不定,字节数由第 1 个字节决定,如下: +//0-250 0 第一个字节值即为数据的真实长度 +func (p Packet) Id() []byte { + return p.raw[0:3] } func (p Packet) Data() []byte { diff --git a/lib/proxy.go b/lib/proxy.go index b6c238f..b245bf9 100644 --- a/lib/proxy.go +++ b/lib/proxy.go @@ -1,6 +1,7 @@ package lib import ( + "fmt" "net" ) @@ -110,6 +111,8 @@ func (p *ProxyConn) PipeClient2Mysql() { p.CloseClient() break } + fmt.Println("client-data:", string(packet.Data())) + fmt.Println("client-id:", packet.Id()) if len(packet.Data()) == 1 && packet.Data()[0] == 1 { // ignore client close command } else { @@ -125,6 +128,8 @@ func (p *ProxyConn) PipeMysql2Client() { p.Close() break } + fmt.Println("server-data:", string(packet.Data())) + fmt.Println("server-id:", packet.Id()) p.SendClient(packet) } } diff --git a/main.go b/main.go index d07f244..b9f0959 100644 --- a/main.go +++ b/main.go @@ -9,9 +9,10 @@ import ( func main() { - mysqlUrl := ":3306" - listen := ":8888" + mysqlUrl := ":3306" // 数据库的端口 + listen := ":8899" // 对外暴露的端口 connCount := runtime.NumCPU() + //connCount := 1 // local 只是开启一个 , navicat 是开启多个连接的,开启一个有问题 server, _ := net.Listen("tcp", listen) connList := make([]lib.ProxyConn, connCount) @@ -26,26 +27,34 @@ func main() { for i := 0; i < connCount; i++ { go func(proxy lib.ProxyConn) { - + // 一: client , mysql的连接信息 + // 初始化mysql client proxy.NewClientConn(server) + // 初始化mysql server proxy.NewMysqlConn(mysqlUrl) + // 类似于登录过程,换token存储于:FinishHandshakePacket , auth操作 err := proxy.Handshake() if err != nil { proxy.Close() } - + // 读取mysql server->client go proxy.PipeMysql2Client() + // 读取mysql client->server go proxy.PipeClient2Mysql() for { - if !proxy.IsClientClose() { - continue - } + // 二: 请求客户端的连接 + // todo 待优化 + //if !proxy.IsClientClose() { + // fmt.Println("xxx", time.Now()) + // continue + //} proxy.NewClientConn(server) - err := proxy.FakeHandshake() - if err != nil { - proxy.CloseClient() - } + // TODO 这个也需要再次auth吗 + //err := proxy.FakeHandshake() + //if err != nil { + // proxy.CloseClient() + //} go proxy.PipeClient2Mysql() }