实现自己的数据库驱动——WireShark分析MySQL网络协议中的数据包(二)

前言

要编写自己的数据库驱动,必须要清楚MySQL协议中各种传输包的数据格式。这里推荐的是WireShark工具,WireShark可以帮我们监听服务器上传输的数据包,上手比较快,而且界面功能都比较友好,最主要是开源的,所以可以免费放心的使用。

要注意的是,如果客户端和数据库服务是在同一台电脑的,会导致WireShark捕获不到数据。因为两个源地址和目的地址是一样的。互相访问时流量并没有经过网卡,WireShark在windows系统上默认使用的是WinPcap来抓包的,用它监控网络的话只能看到经过网卡的流量,看不到访问Localhost的流量。

下图就是WireShark的分析界面了,信息还是比较全面的。

你想输入的替代文字

WireShark抓包

实验环境:MySQL服务器192.168.43.97 ; 客户端 192.168.43.216 ,简单的Python程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#coding=utf-8
import MySQLdb as mdb
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def connectionDB():
con_code = mdb.connect(host='192.168.43.97', user='root', passwd='tdlab401', db='data',
charset='utf8')
cur_code = con_code.cursor()
selectSQL = "SELECT name FROM `paper`;"
cur_code.execute(selectSQL)
rows = cur_code.fetchall()
for row in rows:
print row[0]

if __name__ == '__main__':
connectionDB()
print('start')

客户端发送Query请求,可以看到WireShark捕获的包。

你想输入的替代文字

  1. 首先看第一框中的三次握手,服务端与客户端先是建立连接。
  2. 服务端发送 Server Greeting proto=10 version=8.0.12 这个包就是HandShake
  3. Login Requset user=root db=data是客户端发送的Auth Packet
  4. 服务端认证客户端的Auth Packet之后,返回一个OK Packet
  5. 可以看到我们只发送了一次请求:select name form paper;,但是客户端居然有三次Request Query,实际上第一次的Query是客户端发送set names uft-8 的请求到服务端,指定了客户端和服务器之间传递字符的编码规则为UTF8
    第二次的Request Query是set autocommit=0,表示取消自动提交事务。每个SQL语句所在的事务都需要显示的“commit”才能提交事务。如果你想明确地执行事务,需要禁用自动提交模式并告诉MySQL你想让它在何时提交或回滚有关的修改。
    第三次的Request Query才是我们的SQL请求
  6. 服务端接受并解析了我们的请求,把结果放在Response Packet传回来。

功能界面中我们还可以看到物理层、数据链路层、网络层、传输层,每一层都套自己对应协议的数据头。这块不是我们要研究的重点,重点是应用层上的数据。因为图中我选择的是一个TCP包,所以没能看到应用层。

以上每个Packet都会在后期的博客中慢慢分析。因为清楚的知道数据格式,才能解析出我们想要的数据。

可能会遇到的问题

  1. Host is not allowed to connect to this MySQL server 远程连接被拒绝。

    1. 在装有MySQL的机器上登录 mysql -u root -p密码
    2. 执行use mysql;
    3. 执行update user set host = '%' where user = 'root';这一句执行完可能会报错,不用管它。
    4. 执行FLUSH PRIVILEGES;
  2. 有些人会说WireShark没有捕获到如何数据是怎么回事?

    主要要看一下你捕获的接口列表中,选取有数据波动的网络,如下图选取无线网络连接,才能看到捕获到的包

你想输入的替代文字