Skip to content

Commit 3c083fe

Browse files
committed
2020-09-07 添加 MySQL 模拟服务器
1 parent 8492966 commit 3c083fe

10 files changed

+229
-3
lines changed

MANIFEST

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ bin/mtls-backup
44
bin/mtls-big-files
55
bin/mtls-delete-rows
66
bin/mtls-expired-tables
7+
bin/mtls-fake-mysqld
78
bin/mtls-file-stat
89
bin/mtls-file-truncate
910
bin/mtls-http
@@ -12,8 +13,8 @@ bin/mtls-log
1213
bin/mtls-monitor
1314
bin/mtls-perf-bench
1415
bin/mtls-random-passwd
16+
bin/mtls-rows-diff
1517
bin/mtls-sql-distribution
16-
bin/mtls-sql-playback
1718
bin/mtlsanalysis
1819
bin/mtlsbackup
1920
bin/mtlsbigfiles
@@ -30,6 +31,7 @@ mtls/inspection.py
3031
mtls/mgr.py
3132
mtls/replication.py
3233
mtls/statu.py
34+
mtls/values.py
3335
mtls/variable.py
3436
mtls/kits/__init__.py
3537
mtls/kits/fileformat.py

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ homepage:**http://www.sqlpy.com**
2525
- [表的最晚更新时间统计 -- mtls-file-stat](#表的最晚更新时间统计)
2626
- [找出长时间没有使用过的表 -- mtls-expired-tables](#找出长时间没有使用过的表)
2727
- [批量生成随机密码 -- mtls-random-passwd](#批量生成随机密码)
28+
- [自定义 mysql 消息 -- mtls-fake-mysqld](#自定义mysql消息)
2829
---
2930

3031
## 关于
@@ -897,3 +898,22 @@ t~Gj1-+z8269
897898
```
898899
899900
---
901+
902+
## 自定义mysql消息
903+
模拟 MySQL 服务端向客户端发送特定消息。
904+
905+
启动 MySQL 模拟服务器
906+
```python
907+
mtls-fake-mysqld --host=127.0.0.1 --port=3306 --message='fake news next!'
908+
```
909+
910+
客户端连接到模拟服务器就可以看到对应的消息了。
911+
```bash
912+
mysql -h127.0.0.1 -P3306
913+
ERROR 2020 (HY000): #HY000
914+
fake news next!
915+
```
916+
917+
这个除了可以用来发朋友圈之外,还可以用来检查到指定ip端口的网络特策略是否正常。
918+
919+
---

bin/mtls-fake-mysqld

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#!/usr/bin/evn python3
2+
"""
3+
模拟 MySQL 服务端,目的是做到可以自定义消息。
4+
"""
5+
6+
import os
7+
import struct
8+
import socket
9+
import logging
10+
import argparse
11+
12+
name = os.path.basename(__file__)
13+
logging.basicConfig(
14+
format="%(asctime)s %(levelname)s %(message)s", level=logging.INFO)
15+
16+
17+
class FakeMySQLServer(object):
18+
"""
19+
模拟 MySQL 服务端
20+
"""
21+
22+
def __init__(self, host="0.0.0.0", port=3306, message="MySQL 服务器今天不上班!"):
23+
"""
24+
Parameter
25+
---------
26+
host: str
27+
FakeMySQLServer 要绑定的 IP 地址
28+
29+
port: int
30+
FakeMySQLServer 要监听的端口
31+
32+
message: str
33+
服务端要发给客户端的信息
34+
"""
35+
self.host = host
36+
self.port = port
37+
self.message = " \n" + message + '\n' * 1
38+
39+
def run_server(self):
40+
"""
41+
启动服务端
42+
"""
43+
server_socket = None
44+
try:
45+
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
46+
47+
# 地址重用与端口重用
48+
server_socket.setsockopt(
49+
socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
50+
server_socket.setsockopt(
51+
socket.SOL_SOCKET, socket.SO_REUSEPORT, True)
52+
53+
# 启动监听队列长度设置为 5
54+
server_socket.bind((self.host, self.port))
55+
server_socket.listen(5)
56+
57+
while True:
58+
try:
59+
# 循环接收客户端的连接
60+
client, _ = server_socket.accept()
61+
62+
# 对消息进行编码
63+
bytes_message = self.message.encode('utf8') + b'\x00'
64+
payload_len = 9 + len(bytes_message)
65+
66+
# payload-len seqence-id error-packet-content
67+
packet = struct.pack("<I", payload_len)[
68+
0:3] + b'\x00' + b'\xff\xe4\x07\x23\x48\x59\x30\x30\x30' + bytes_message
69+
client.send(packet)
70+
71+
# 关闭连接
72+
client.close()
73+
except Exception as err:
74+
logging.error(err)
75+
logging.exception(err)
76+
77+
finally:
78+
if hasattr(client, 'close'):
79+
client.close()
80+
81+
except Exception as err:
82+
logging.error(err)
83+
logging.exception(err)
84+
finally:
85+
if hasattr(server_socket, 'close'):
86+
server_socket.close()
87+
88+
89+
def parser_cmd_args() -> argparse.ArgumentParser:
90+
"""
91+
处理命令行参数
92+
"""
93+
parser = argparse.ArgumentParser(name)
94+
parser.add_argument('--host', type=str,
95+
default='0.0.0.0', help='Fake-MySQL-Server 要绑定的IP')
96+
parser.add_argument('--port', type=int, default=3306,
97+
help="Fake-MySQL-Server 要监听的端口")
98+
parser.add_argument('--message', type=str,
99+
default="MySQL 服务器今天不上班!", help="要发送给客户端的信息")
100+
args = parser.parse_args()
101+
return args
102+
103+
104+
if __name__ == "__main__":
105+
args = parser_cmd_args()
106+
fake = FakeMySQLServer(args.host, args.port, args.message)
107+
fake.run_server()

bin/mtls-rows-diff

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/evn python3
2+
# encoding:utf8
3+
4+
"""
5+
比较两个文件中不同的行
6+
"""
7+
8+
import os
9+
import sys
10+
import argparse
11+
12+
13+
def parser_args():
14+
parser = argparse.ArgumentParser()
15+
parser.add_argument('-s', '--source', type=str,
16+
default='/tmp/source.txt', help='源文件路径')
17+
parser.add_argument('-t', '--target', type=str,
18+
default='/tmp/target.txt', help='目标文件路径')
19+
return parser.parse_args()
20+
21+
22+
def diff(source_file: str, target_file: str) -> set:
23+
"""
24+
计算 source_file 中有,但是 target_file 中没有的行
25+
26+
Parmter
27+
------
28+
source_file: str 源文件全路径
29+
target_file: str 目标文件全路径
30+
"""
31+
if not os.path.isfile(source_file):
32+
print(f"{source_file} is not a file or not exists.")
33+
sys.exit(0)
34+
35+
if not os.path.isfile(target_file):
36+
print(f"{target_file} is not a file or not exists.")
37+
sys.exit(0)
38+
39+
with open(source_file, 'r') as source:
40+
source_rows = set()
41+
for line in source:
42+
source_rows.update(set(line.strip()))
43+
44+
with open(target_file) as target:
45+
target_rows = set()
46+
for line in target:
47+
target_rows.update(set(line.strip()))
48+
49+
d = source_rows - target_rows
50+
51+
for line in d:
52+
print(d)
53+
54+
55+
def main():
56+
args = parser_args()
57+
diff(args.source, args.target)
58+
59+
60+
if __name__ == "__main__":
61+
main()
32.5 KB
Binary file not shown.
32.5 KB
Binary file not shown.
32.5 KB
Binary file not shown.
33.7 KB
Binary file not shown.

mtls/values.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""
2+
根据给定的类型完全随机的从它的值域中取值。
3+
"""
4+
import random
5+
6+
7+
class Number(object):
8+
"""
9+
10+
"""
11+
begin = 0
12+
end = 128
13+
14+
def __getitem__(self, index):
15+
"""
16+
"""
17+
return random.randint(self.begin, self.end)
18+
19+
def __len__(self):
20+
"""
21+
"""
22+
return self.end - self.begin
23+
24+
25+
class Int(Number):
26+
begin = 0
27+
end = (1 << 32) - 1
28+
29+
30+
class Float(Int):
31+
begin = 0
32+
end = (1 << 32) - 1
33+
34+
def __getitem__(self, index):
35+
return random.randint(self.begin, self.end - 1) + random.random()

setup.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
news_scripts = ['bin/mtls-big-files', 'bin/mtls-delete-rows', 'bin/mtls-file-truncate',
77
'bin/mtls-http', 'bin/mtls-log', 'bin/mtls-monitor', 'bin/mtls-backup',
88
'bin/mtls-perf-bench', 'bin/mtls-kill-all-conections', 'bin/mtls-sql-distribution',
9-
'bin/mtls-file-stat', 'bin/mtls-expired-tables', 'bin/mtls-sql-playback', 'bin/mtls-random-passwd']
9+
'bin/mtls-file-stat', 'bin/mtls-expired-tables', 'bin/mtls-random-passwd',
10+
'bin/mtls-rows-diff', 'bin/mtls-fake-mysqld']
1011

1112
scripts = olds_scripts + news_scripts
1213

1314
setup(name='mysqltools-python',
14-
version='2.20.06.01',
15+
version='2.20.09.07',
1516
scripts=scripts,
1617
packages=['mtls', 'mtls.kits'],
1718
maintainer='Neeky',

0 commit comments

Comments
 (0)