摘 要
1.模拟实现DNS域名解析系统
2.设计思路:分别模拟本地域名服务器、根域名服务器,顶级域名服务器和权限域名服务器,在主机和本地域名服务器之间采用递归查询,本地域名服务器和其它服务器之间使用迭代查询,最后把查询结果返回到主机中。
3.解决方案如下:
① 用数据库模拟本地域名服务器,分别用函数模拟根域名服务器,顶级域名服务器和权限域名服务器
② 通过对数据库的查询和存储来模拟主机向本地域名服务器的查询和本地域名服务器存储域名和IP的对应关系。
③ 把本地域名服务器用一个函数表示,通过对其它服务器函数的调用来模拟实现查询功能
④功能图
一、项目设计和实现
1 .总体设计
1.1域名解析系统的层次关系
1.2功能模块划分
-
- 本地域名服务器模块:local(domain)函数,传入域名,返回域名对应的IP地址
- 根域名服务器模块:root(domain)函数,传入域名,返回顶级域名服务器的IP地址
- 顶级域名服务器模块:top_com(domain),top_org(domain)等函数,传入域名,返回权限域名服务器的IP地址
- 权限域名服务器模块:permissions_com(domain),permissions_org(domain)等函数,传入域名,返回IP地址
如果在顶级域名服务器就已经获取到完整域名的IP地址,则无需继续向下进行,直接将IP地址返回给本地域名服务器,本地域名服务器向主机返回并且在本地存储。
1.3数据库设计
创建一个名为domain_ip的表,表的列名分别是domain和IP,分别用来存储域名和IP地址
1.2 功能设计
①主机和本地域名服务器之间的查询功能由本地数据库实现,在执行查询功能时直接查询本地数据库
- 根域名服务器,顶级域名服务器,权限域名服务器分别用函数封装,域名和IP的对应关系也存储在函数中。本地域名服务器和根域名服务器、顶级域名服务器、权限域名服务器之间的查询功能都由调用函数实现。
- 如果本地域名服务器中没有对应域名的IP时,在执行查询后把对应关系也存储到本地数据库中
- 把本地域名服务器也封装到一个函数,通过对各函数的调用来实现迭代查询
1.3 系统实现
(各功能模块的编程实现)
①连接数据库并获取内容
conn = Connection(
host='localhost',
port=3306,
user='root',
password='123456',
autocommit=True
)
# 获取游标对象
cursor = conn.cursor()
conn.select_db("test2") # 选择数据库
cursor.execute("select * from domain_ip;") # 使用游标对象执行sql语句
result: tuple = cursor.fetchall() # 获取查询结果,数据存储在一个元组中,每一条数据是一个元素
②根域名服务器的封装
def root(domain):
res = domain.split('.')[-1]
root_dict = {
'com': '192.168.1.1',
'org': '192.168.1.2',
'cn': '192.168.1.3'
}
return root_dict[res]
顶级域名服务器的封装
def top_com(domain):
res = domain.split('.')[-2] + '.' + domain.split('.')[-1]
com_root_dict = {
'example.com': '192.168.2.1',
'example1.com': '192.168.2.2',
'example2.com': '192.168.2.3'
}
return com_root_dict[res]
权限域名服务器的封装
def permissions_com(domain):
res = domain.split('.')[-3] + '.' + domain.split('.')[-2] + '.' + domain.split('.')[-1]
permissions_com_dict = {
"subdomain.example.com": "192.168.5.1",
"subdomain.example1.com": "192.168.5.2",
"subdomain.example2.com": "192.168.5.3"
}
return permissions_com_dict[res]
③查询完成之后把对应关系存储到数据库中
cursor.execute(f"insert into domain_ip values ('{domain}','{res}')")
④封装本地域名服务器并完成查询功能
def local(domain):
# 判断是否在本地域名服务器中有存储
if domain in local_server:
print('在本地域名服务器中查询到')
return local_server[domain]
# 访问根域名服务器,得到顶级域名服务器的ip
top_ip = root(domain) # example.com
# 根据返回的ip地址访问顶级域名服务器
if top_ip == '192.168.1.1':
permissions_ip = top_com(domain)
# 如果已经找到域名对应的IP后直接返回
if domain.split('.')[0] == domain.split('.')[-2]:
# 添加到本地域名服务器中
local_server[domain] = permissions_ip
cursor.execute(f"insert into domain_ip values ('{domain}','{permissions_ip}')")
return permissions_ip
# 如果还没找到继续访问权限域名服务器
# 模拟根据ip地址访问权限域名服务器
if permissions_ip == '192.168.2.1' or '192.168.2.2' or '192.168.2.3':
res = permissions_com(domain)
local_server[domain] = res
cursor.execute(f"insert into domain_ip values ('{domain}','{res}')")
# 把结果返回给主机
return res
elif top_ip == '192.168.1.2':
permissions_ip = top_org(domain)
if domain.split('.')[0] == domain.split('.')[-2]:
local_server[domain] = permissions_ip
cursor.execute(f"insert into domain_ip values ('{domain}','{permissions_ip}')")
return permissions_ip
if permissions_ip == '192.168.3.1' or '192.168.3.2' or '192.168.3.3':
res = permissions_org(domain)
local_server[domain] = res
cursor.execute(f"insert into domain_ip values ('{domain}','{res}')")
return res
elif top_ip == '192.168.1.3':
permissions_ip = top_cn(domain)
if domain.split('.')[0] == domain.split('.')[-2]:
local_server[domain] = permissions_ip
cursor.execute(f"insert into domain_ip values ('{domain}','{permissions_ip}')")
return permissions_ip
if permissions_ip == '192.168.4.1' or '192.168.4.2' or '192.168.4.3':
res = permissions_cn(domain)
local_server[domain] = res
cursor.execute(f"insert into domain_ip values ('{domain}','{res}')")
return res
二、系统运行和测试
1.功能模块测试
①数据库连接和内容获取
②本地域名服务器和根域名服务器的查询功能(以subdomain.example.com为例,访问需要查询根域名服务器,顶级域名服务器和权限域名服务器)
在根域名服务器中打印要返回给本地域名服务器的IP地址
③本地域名服务器和顶级域名服务器的查询功能
在顶级域名服务器中添加打印语句,打印example.com对应服务器的IP地址
④本地域名服务器和权限域名服务器的查询功能
在权限域名服务器中添加打印语句,测试从权限域名服务器中返回的结果是否正确
2.系统整体功能测试
①本地域名服务器中有要查询域名的对应关系
②本地域名服务器中有要查询域名的对应关系
三、源码
from pymysql import Connection
# 用于接收数据库中的数据
local_server = {}
# 获取到MySQL数据库的链接对象
conn = Connection(
host='localhost',
port=3306,
user='root',
password='123456',
autocommit=True
)
# 获取游标对象
cursor = conn.cursor()
conn.select_db("test2") # 选择数据库
cursor.execute("select * from domain_ip;") # 使用游标对象执行sql语句
result: tuple = cursor.fetchall() # 获取查询结果,数据存储在一个元组中,每一条数据是一个元素
for i in result: # 如果没有返回结果,则无需执行下面语句,如创建表
local_server[i[0]] = i[1] # 添加到字典中
# 本地域名服务器
def local(domain):
# 判断是否在本地域名服务器中有存储
if domain in local_server:
print('在本地域名服务器中查询到')
return local_server[domain]
# 访问根域名服务器,得到顶级域名服务器的ip
top_ip = root(domain) # example.com
# 根据返回的ip地址访问顶级域名服务器
if top_ip == '192.168.1.1':
permissions_ip = top_com(domain)
# 如果已经找到域名对应的IP后直接返回
if domain.split('.')[0] == domain.split('.')[-2]:
# 添加到本地域名服务器中
local_server[domain] = permissions_ip
cursor.execute(f"insert into domain_ip values ('{domain}','{permissions_ip}')")
return permissions_ip
# 如果还没找到继续访问权限域名服务器
# 模拟根据ip地址访问权限域名服务器
if permissions_ip == '192.168.2.1' or '192.168.2.2' or '192.168.2.3':
res = permissions_com(domain)
local_server[domain] = res
cursor.execute(f"insert into domain_ip values ('{domain}','{res}')")
# 把结果返回给主机
return res
elif top_ip == '192.168.1.2':
permissions_ip = top_org(domain)
if domain.split('.')[0] == domain.split('.')[-2]:
local_server[domain] = permissions_ip
cursor.execute(f"insert into domain_ip values ('{domain}','{permissions_ip}')")
return permissions_ip
if permissions_ip == '192.168.3.1' or '192.168.3.2' or '192.168.3.3':
res = permissions_org(domain)
local_server[domain] = res
cursor.execute(f"insert into domain_ip values ('{domain}','{res}')")
return res
elif top_ip == '192.168.1.3':
permissions_ip = top_cn(domain)
if domain.split('.')[0] == domain.split('.')[-2]:
local_server[domain] = permissions_ip
cursor.execute(f"insert into domain_ip values ('{domain}','{permissions_ip}')")
return permissions_ip
if permissions_ip == '192.168.4.1' or '192.168.4.2' or '192.168.4.3':
res = permissions_cn(domain)
local_server[domain] = res
cursor.execute(f"insert into domain_ip values ('{domain}','{res}')")
return res
# 根域名服务器
def root(domain):
res = domain.split('.')[-1]
root_dict = {
'com': '192.168.1.1',
'org': '192.168.1.2',
'cn': '192.168.1.3'
}
# print(root_dict[res])
return root_dict[res]
# 顶级域名服务器,com
def top_com(domain):
res = domain.split('.')[-2] + '.' + domain.split('.')[-1]
com_root_dict = {
'example.com': '192.168.2.1',
'example1.com': '192.168.2.2',
'example2.com': '192.168.2.3'
}
# print(com_root_dict[res])
return com_root_dict[res]
# 顶级域名服务器,org
def top_org(domain):
res = domain.split('.')[-2] + '.' + domain.split('.')[-1]
org_root_dict = {
'example.org': '192.168.3.1',
'example1.org': '192.168.3.2',
'example2.org': '192.168.3.3'
}
return org_root_dict[res]
# 顶级域名服务器,cn
def top_cn(domain):
res = domain.split('.')[-2] + '.' + domain.split('.')[-1]
cn_root_dict = {
'example.cn': '192.168.4.1',
'example1.cn': '192.168.4.2',
'example2.cn': '192.168.4.3'
}
return cn_root_dict[res]
# 权限域名服务器,com
def permissions_com(domain):
res = domain.split('.')[-3] + '.' + domain.split('.')[-2] + '.' + domain.split('.')[-1]
permissions_com_dict = {
"subdomain.example.com": "192.168.5.1",
"subdomain.example1.com": "192.168.5.2",
"subdomain.example2.com": "192.168.5.3"
}
# print(permissions_com_dict[res])
return permissions_com_dict[res]
# 权限域名服务器,org
def permissions_org(domain):
res = domain.split('.')[-3] + '.' + domain.split('.')[-2] + '.' + domain.split('.')[-1]
permissions_org_dict = {
"subdomain.example.org": "192.168.6.1",
"subdomain.example1.org": "192.168.6.2",
"subdomain.example2.org": "192.168.6.3"
}
return permissions_org_dict[res]
# 权限域名服务器,cn
def permissions_cn(domain):
res = domain.split('.')[-3] + '.' + domain.split('.')[-2] + '.' + domain.split('.')[-1]
permissions_cn_dict = {
"subdomain.example.cn": "192.168.7.1",
"subdomain.example1.cn": "192.168.7.2",
"subdomain.example2.cn": "192.168.7.3"
}
return permissions_cn_dict[res]
# print(local_server)
domain = input('domain:')
print(local(domain))
conn.close()
注:实现DNS域名解析系统也可以采用另外一种方式