更新代码

master
bettleChen 11 months ago
parent 6ef7d559c2
commit 9e62d0b470

@ -1,143 +0,0 @@
# 导入模块
import pymysql
# 连接本地数据库
db = pymysql.connect(
host='localhost', # 例:127.0.0.1 本地数据库地址
port=3306, # 端口号
user='root', # 用户id
passwd='123456', # 用户密码
db='demodb' # 连接的数据库
)
cursor = db.cursor()
# print(cursor)
# 设置查找simhost表的函数
def get_simhost_alldata():
# 获取simhost数据库中所有的数据
sql = '''
select * from simhost
'''
cursor.execute(sql)
# 获取全部数据
test = cursor.fetchall()
# test = pd.read_sql(sql,db)
host_data_all = []
for i in test:
# 在这里对数据进行整理...
ID = i[0]
ObjID = i[1]
ObjType = i[2]
ObjLable = i[3]
IPAddr = i[4]
ObjX = i[5]
ObjY = i[6]
MACAddr = i[7]
ObjShow = i[8]
host_data = {
'ID': ID,
'ObjID': ObjID,
'ObjType': ObjType,
'ObjLable': ObjLable,
'IPAddr': IPAddr,
'ObjX': ObjX,
'ObjY': ObjY,
'MACAddr': MACAddr,
'ObjShow': ObjShow
}
host_data_all.append(host_data)
# print(host_data)
# print(test) # 错误
# cursor.close() # 关闭游标
# db.close() # 关闭数据库连接
return host_data_all
# 建立条件查询将ObjShow==1的值全部获取
def Select_ObjShow():
sql = '''select * from simhost where ObjShow=1'''
cursor.execute(sql)
objshow_select = cursor.fetchall()
# print(objshow_select)
objshow_select_all = []
for i in objshow_select:
# 在这里对数据进行整理...
ID = i[0]
ObjID = i[1]
ObjType = i[2]
ObjLable = i[3]
IPAddr = i[4]
ObjX = i[5]
ObjY = i[6]
MACAddr = i[7]
ObjShow = i[8]
host_data = {
'ID': ID,
'ObjID': ObjID,
'ObjType': ObjType,
'ObjLable': ObjLable,
'IPAddr': IPAddr,
'ObjX': ObjX,
'ObjY': ObjY,
'MACAddr': MACAddr,
'ObjShow': ObjShow
}
objshow_select_all.append(host_data)
# print(objshow_select_all)
return objshow_select_all
# 设置联合查询ipAddr的地址
def select_and_ip(id):
data_all = []
sql = '''select ipaddr.ipaddr from ipaddr inner join simhost on ipaddr.sim_id = simhost.id where simhost.id=%s'''
cursor.execute(sql,id)
data = cursor.fetchall()
for item in data:
# print(item[0])
data_all.append(item[0])
# print(data_all)
return data_all
# 创建查询ObjLable列的函数
def select_ObjLable():
data_all = []
sql = '''
select objlable from simhost
'''
cursor.execute(sql)
test = cursor.fetchall()
for item in test:
data_all.append(item[0])
# print(data_all)
return data_all
# 在这个位置添加一个修改objshow列的数据函数
def reve_objshow():
# 将所有的对象全转换为objshow = 0
sql = '''update simhost set objshow = 0 where objshow = 1'''
cursor.execute(sql)
db.commit()
return None
def reve_after(after_data):
# 将获取的数据进行循环
for item in after_data:
sql = '''update simhost set objshow = 1 where objlable = %s'''
cursor.execute(sql, item)
db.commit()
return None
if __name__ == '__main__':
# print(get_simhost_alldata())
# print(select_ObjLable())
reve_objshow()
after_data = ['A','R1','B']
reve_after(after_data)

@ -1,197 +0,0 @@
# 尝试用sqlite3数据库试试
import sqlite3
conn = sqlite3.connect('internet.db')
cursor = conn.cursor()
# 设置创建数据库的函数
def create_simhost():
sql = '''DROP TABLE IF EXISTS `simhost`'''
cursor.execute(sql)
sql_simhost = '''CREATE TABLE simhost
(
id integer primary key ,
ObjID varchar(20),
ObjType int,
Objlable varchar(20),
IPAddr varchar(64),
ObjX int,
ObjY int,
MACAddr varchar(64),
ObjShow int
);'''
cursor.execute(sql_simhost)
return None
#建立数据表ipaddr的函数
def create_ipaddr():
sql = '''DROP TABLE IF EXISTS `ipaddr`'''
cursor.execute(sql)
sql_ipaddr = '''CREATE TABLE ipaddr
(
id integer primary key ,
ipaddr varchar(25),
sim_id int,
foreign key (sim_id) references simhost(id)
);'''
cursor.execute(sql_ipaddr)
return None
# 设置两个插入数据函数
def insert_simhost():
# 需要插入的数据
data_simhost = [
(1, 'SH01', 1, 'A', '101.11.1.2', 170, 120, 'MAC01', 1),
(2, 'SR01', 2, 'R1', '102.10.1.1', 250, 160, 'MAC02', 1),
(3, 'SR02', 2, 'R2', '102.10.5.1', 370, 130, 'MAC03', 1),
(4, 'SR03', 2, 'R4', '102.10.6.1', 400, 200, 'MAC04', 1),
(5, 'SR04', 2, 'R5', '111.12.1.1', 480, 260, 'MAC05', 1),
(6, 'SH02', 1, 'D', '201.21.1.2', 420, 330, 'MAC06', 1),
(7, 'SHO3', 1, 'B', '101.11.1.8', 250, 240, 'MAC07', 0),
(8, 'SR05', 2, 'R3', '102.10.6.2', 520, 160, 'MAC08', 0),
(9, 'SH04', 1, 'C', '201.21.1.5', 540, 320, 'MAC09', 0),
]
sql = '''INSERT INTO simhost (id,ObjID,ObjType,Objlable,IPAddr,ObjX,ObjY,MACAddr,ObjShow)
VALUES (?,?,?,?,?,?,?,?,?)'''
cursor.executemany(sql,data_simhost)
conn.commit()
return None
def insert_ipaddr():
# 需要插入的数据
data_ipaddr = [
(1, '101.11.1.1', 1),
(2, '102.10.1.1', 2),
(3, '102.10.5.1', 3),
(4, '111.12.5.1', 4),
(5, '201.21.1.1', 5),
]
sql = '''INSERT INTO ipaddr (id,ipaddr,sim_id) VALUES (?,?,?)'''
cursor.executemany(sql,data_ipaddr)
conn.commit()
return None
# 设置获取数据库中所有数据的函数
def get_simhost_alldata():
sql = '''SELECT * FROM simhost'''
cursor.execute(sql)
data = cursor.fetchall()
# print(data)
all_data = []
for item in data:
ID = item[0]; ObjID = item[1]; ObjType = item[2]
ObjLable = item[3]; IPAddr = item[4]; ObjX = item[5]
ObjY = item[6]; MACAddr = item[7]; ObjShow = item[8]
host_data = {
'ID': ID,'ObjID': ObjID,'ObjType': ObjType,
'ObjLable': ObjLable,'IPAddr': IPAddr,'ObjX': ObjX,
'ObjY': ObjY,'MACAddr': MACAddr,'ObjShow': ObjShow
}
all_data.append(host_data)
return all_data
# 建立条件查询将ObjShow==1的值全部取出
def Select_ObjShow():
sql = '''SELECT * FROM simhost WHERE ObjShow=1'''
cursor.execute(sql)
objshow_data = cursor.fetchall()
# print(objshow_data)
objshow_data_all = []
for item in objshow_data:
ID = item[0]; ObjID = item[1]; ObjType = item[2]
ObjLable = item[3]; IPAddr = item[4]; ObjX = item[5]
ObjY = item[6]; MACAddr = item[7]; ObjShow = item[8]
host_data = {
'ID': ID,'ObjID': ObjID,'ObjType': ObjType,
'ObjLable': ObjLable,'IPAddr': IPAddr,'ObjX': ObjX,
'ObjY': ObjY,'MACAddr': MACAddr,'ObjShow': ObjShow
}
objshow_data_all.append(host_data)
return objshow_data_all
# 建立联合查询ipaddr的地址
def select_and_ip(id):
data_all = []
sql = '''SELECT ipaddr.ipaddr FROM ipaddr INNER JOIN simhost ON ipaddr.sim_id = simhost.id WHERE simhost.id=?'''
cursor.execute(sql, (id,))
data = cursor.fetchall()
for item in data:
# print(item[0])
data_all.append(item[0])
return data_all
# 建立查询ObjLable列的函数
def select_ObjLable():
data_all = []
sql = '''SELECT objlable FROM simhost'''
cursor.execute(sql)
data = cursor.fetchall()
for item in data:
data_all.append(item[0])
# print(data_all)
return data_all
# 建立这个位置添加一个修改objshow列的数据函数
def reve_objshow():
sql = '''UPDATE simhost SET objshow=0 WHERE objshow=1'''
cursor.execute(sql)
conn.commit()
return None
# 建立一个修改指定数据的函数objshow
def reve_after(after_data):
# 将获取的数据进行循环
for item in after_data:
sql = '''UPDATE simhost SET objshow=1 WHERE objlable=?'''
cursor.execute(sql, (item,))
conn.commit()
return None
# 建立一个通过查询ObjLable并返回ObjID的函数
def select_ObjLable_ObjID(objlable):
sql = '''SELECT objx,objy,objid,objshow FROM simhost WHERE objlable=?'''
cursor.execute(sql, (objlable,))
old_data = cursor.fetchall()
new_data = old_data[0]
# print(new_data)
return new_data
# 建立函数通过指定的ObjID来查找所有的数据
def Select_ObjID(array):
array_all_data = [] # 用来获取所有的对应的数据并放入其中
sql = '''SELECT * FROM simhost WHERE objlable=?'''
for item in array:
cursor.execute(sql, (item,))
data = cursor.fetchall()
# print(data)
ID = data[0][0];ObjID = data[0][1];ObjType = data[0][2]
ObjLable = data[0][3];IPAddr = data[0][4];ObjX = data[0][5]
ObjY = data[0][6];MACAddr = data[0][7];ObjShow = data[0][8]
host_data = {
'ID': ID, 'ObjID': ObjID, 'ObjType': ObjType,
'ObjLable': ObjLable, 'IPAddr': IPAddr, 'ObjX': ObjX,
'ObjY': ObjY, 'MACAddr': MACAddr, 'ObjShow': ObjShow
}
array_all_data.append(host_data)
return array_all_data
if __name__ == '__main__':
# create_simhost()
# insert_simhost()
# create_ipaddr()
# insert_ipaddr()
# get_data_sinhost()
# print(get_simhost_alldata())
# print(Select_ObjShow())
# print(select_and_ip(1))
# print(select_ObjLable())
# reve_objshow()
# after_data = ['A', 'R1', 'B']
# reve_after(after_data)
# select_ObjLable_ObjID('A')
# array = ['A','B']
# print(Select_ObjID(array))
pass

@ -1,117 +0,0 @@
# 在这个文件里画出详情
# 创建函数用来画出详情
import time
class Detail_Show():
def __init__(self, cv, img_detail, move_data):
self.cv = cv
self.move_data = move_data
self.img_detail = img_detail
def show_detail(self):
# time.sleep(5)
self.detail_data_all = []
# 通过获取的move_data数据来画出详情表
for item in self.move_data:
detail_data_x = item[0]+20
detail_data_y = item[1]
detail_type = item[3]
detail_data = (detail_data_x,detail_data_y,detail_type)
self.detail_data_all.append(detail_data)
self.cv.create_image(detail_data_x,detail_data_y, image=self.img_detail, tags='detail') # 完成
return self.detail_data_all
# 建立一个用来画出详情的类
class Show_green_detail():
def __init__(self, cv, item):
self.cv = cv
self.item = item
# 建立画出对象详情的函数
def draw_detail(self):
# 判断type对象来画出详情表
if self.item[2] == 1: # 当type对象为1 画出主机详情图
# 在这里画出详情图
frist_x = self.item[0] # 获取frist_x
frist_y = self.item[1] # 获取frist_y
# 这里缺少一个删除其他详情的步骤
# 画出连接详情表的线
self.cv.delete('line')
self.cv.create_line((frist_x,frist_y),(frist_x+40,frist_y),(frist_x+45,frist_y-30),fill='#94D050',tags='line')
# 画出详情表
self.detail_true = self.cv.create_rectangle(frist_x+30,frist_y-120,frist_x+180,frist_y-30,outline='#94D050',tags='line')
# 画出相应的绿条数据
self.cv.create_text(frist_x+50,frist_y-110,text='应用层',tags='line')
self.cv.create_text(frist_x+50,frist_y-87,text='传输层',tags='line')
self.cv.create_text(frist_x+50,frist_y-64,text='IP 层',tags='line')
self.cv.create_text(frist_x+50,frist_y-42,text='链路层',tags='line')
# 画出 右侧绿色和蓝色的类进度条
# 应用层
self.cv.create_rectangle(frist_x+177,frist_y-115,frist_x+150,frist_y-100,fill='#94D050',outline='#94D050',tags='line')
self.cv.create_rectangle(frist_x+148,frist_y-115,frist_x+128,frist_y-100,fill='#00B0F0',outline='#00B0F0',tags='line')
# 传输层
self.cv.create_rectangle(frist_x + 177, frist_y - 95, frist_x + 140, frist_y - 80, fill='#94D050',
outline='#94D050', tags='line')
self.cv.create_rectangle(frist_x + 138, frist_y - 95, frist_x + 113, frist_y - 80, fill='#00B0F0',
outline='#00B0F0', tags='line')
# IP 层
self.cv.create_rectangle(frist_x + 177, frist_y - 73, frist_x + 130, frist_y - 58, fill='#94D050',
outline='#94D050', tags='line')
self.cv.create_rectangle(frist_x + 128, frist_y - 73, frist_x + 98, frist_y - 58, fill='#00B0F0',
outline='#00B0F0', tags='line')
# 传输层
self.cv.create_rectangle(frist_x + 177, frist_y - 50, frist_x + 113, frist_y - 35, fill='#94D050',
outline='#94D050', tags='line')
self.cv.create_rectangle(frist_x + 111, frist_y - 50, frist_x + 78, frist_y - 35, fill='#00B0F0',
outline='#00B0F0', tags='line')
elif self.item[2] == 2: # 当type对象为2 画出路由器详情图
# print(2)
frist_x = self.item[0] # 获取frist_x
frist_y = self.item[1] # 获取frist_y
# 这里缺少一个删除其他详情的步骤
# 画出连接详情表的线
self.cv.delete('line')
self.cv.create_line((frist_x, frist_y), (frist_x + 40, frist_y), (frist_x + 45, frist_y - 30),
fill='#94D050', tags='line')
# 画出详情表 如果需要全覆盖则需要添加一个fill
self.detail_true = self.cv.create_rectangle(frist_x + 30, frist_y - 120, frist_x + 180, frist_y - 30,
outline='#94D050', tags='line')
# 画出相应的绿条数据
self.cv.create_text(frist_x + 50, frist_y - 110, text='应用层', tags='line')
self.cv.create_text(frist_x + 50, frist_y - 87, text='传输层', tags='line')
self.cv.create_text(frist_x + 50, frist_y - 64, text='IP 层', tags='line')
self.cv.create_text(frist_x + 50, frist_y - 42, text='链路层', tags='line')
# 画出 右侧绿色和蓝色的类进度条
# 应用层
self.cv.create_rectangle(frist_x + 177, frist_y - 115, frist_x + 150, frist_y - 100, fill='#D3D3D3',
outline='#D3D3D3', tags='line')
self.cv.create_rectangle(frist_x + 148, frist_y - 115, frist_x + 128, frist_y - 100, fill='#D3D3D3',
outline='#D3D3D3', tags='line')
# 传输层
self.cv.create_rectangle(frist_x + 177, frist_y - 95, frist_x + 140, frist_y - 80, fill='#D3D3D3',
outline='#D3D3D3', tags='line')
self.cv.create_rectangle(frist_x + 138, frist_y - 95, frist_x + 113, frist_y - 80, fill='#D3D3D3',
outline='#D3D3D3', tags='line')
# IP 层
self.cv.create_rectangle(frist_x + 177, frist_y - 73, frist_x + 130, frist_y - 58, fill='#94D050',
outline='#94D050', tags='line')
self.cv.create_rectangle(frist_x + 128, frist_y - 73, frist_x + 98, frist_y - 58, fill='#00B0F0',
outline='#00B0F0', tags='line')
# 传输层
self.cv.create_rectangle(frist_x + 177, frist_y - 50, frist_x + 113, frist_y - 35, fill='#94D050',
outline='#94D050', tags='line')
self.cv.create_rectangle(frist_x + 111, frist_y - 50, frist_x + 78, frist_y - 35, fill='#00B0F0',
outline='#00B0F0', tags='line')
return None
if __name__ == '__main__':
pass

@ -1,70 +0,0 @@
# 导入函数
from data_crud_sqlite import *
'''创建类来处理函数'''
class Show_Right_All():
def __init__(self,cv,all_data):
self.cv = cv
self.all_data = all_data
# 创建函数 来处理获取的数据
def Show_img(self,img_host,img_router):
self.loca_all = [] # 定义一个数组用来存数据
# 将获取的所有数据处理
for item in self.all_data:
ObjX = item['ObjX']
ObjY = item['ObjY']
ObjID = item['ObjID']
loca = (ObjX, ObjY)
self.loca_all.append(loca)
# 显示图片
if item['ObjType'] == 1:
self.cv.create_image(ObjX, ObjY, image=img_host, tags=ObjID)
# elif item['ObjType'] == 2:
else:
self.cv.create_image(ObjX, ObjY, image=img_router, tags=ObjID)
# 显示ObjLable
if item['ObjLable'] == 'A':
self.cv.create_text(ObjX, ObjY+27, text=item['ObjLable'], font=('蔚然雅黑',16,'bold'),fill='#C00000', tags=item['ObjLable'])
self.cv.create_text(ObjX, ObjY-32, text=item['IPAddr'], font=('蔚然雅黑',10,'bold'),fill='#C00000', tags=item['IPAddr'])
elif item['ObjLable'] == 'R1':
self.cv.create_text(ObjX+15, ObjY+25, text=item['ObjLable'], font=('蔚然雅黑',16,'bold'),fill='#C00000', tags=item['ObjLable'])
self.cv.create_text(ObjX-67, ObjY, text=item['IPAddr'], font=('蔚然雅黑', 10, 'bold'), fill='#C00000',
tags=item['IPAddr'])
# 通过联表查询获取IP地址
ip_data_R1 = select_and_ip(2)
# print(ip_data_R1)
self.cv.create_text(ObjX+30, ObjY-30, text= ip_data_R1, font=('蔚然雅黑',10,'bold'),fill='#C00000', tags=ip_data_R1)
elif item['ObjLable'] == 'R2':
self.cv.create_text(ObjX-17, ObjY+25, text=item['ObjLable'], font=('蔚然雅黑',16,'bold'),fill='#C00000', tags=item['ObjLable'])
self.cv.create_text(ObjX, ObjY - 32, text=item['IPAddr'], font=('蔚然雅黑', 10, 'bold'), fill='#C00000',
tags=item['IPAddr'])
elif item['ObjLable'] == 'R4':
self.cv.create_text(ObjX-35, ObjY, text=item['ObjLable'], font=('蔚然雅黑',16,'bold'),fill='#C00000', tags=item['ObjLable'])
self.cv.create_text(ObjX+20, ObjY - 29, text=item['IPAddr'], font=('蔚然雅黑', 10, 'bold'), fill='#C00000',
tags=item['IPAddr'])
ip_data_R4 = select_and_ip(4)
self.cv.create_text(ObjX - 10, ObjY + 26, text=ip_data_R4, font=('蔚然雅黑', 10, 'bold'), fill='#C00000',
tags=ip_data_R4)
elif item['ObjLable'] == 'R5':
self.cv.create_text(ObjX, ObjY+27, text=item['ObjLable'], font=('蔚然雅黑',16,'bold'),fill='#C00000', tags=item['ObjLable'])
self.cv.create_text(ObjX-67, ObjY - 12, text=item['IPAddr'], font=('蔚然雅黑', 10, 'bold'), fill='#C00000',
tags=item['IPAddr'])
ip_data_R5 = select_and_ip(5)
self.cv.create_text(ObjX - 67, ObjY + 3, text=ip_data_R5, font=('蔚然雅黑', 10, 'bold'), fill='#C00000',
tags=ip_data_R5)
elif item['ObjLable'] == 'D':
self.cv.create_text(ObjX-31, ObjY+10, text=item['ObjLable'], font=('蔚然雅黑',16,'bold'),fill='#C00000', tags=item['ObjLable'])
self.cv.create_text(ObjX, ObjY + 27, text=item['IPAddr'], font=('蔚然雅黑', 10, 'bold'), fill='#C00000',
tags=item['IPAddr'])
elif item['ObjLable'] == 'C':
self.cv.create_text(ObjX+25, ObjY-27, text=item['ObjLable'], font=('蔚然雅黑',16,'bold'),fill='#C00000', tags=item['ObjLable'])
self.cv.create_text(ObjX, ObjY + 27, text=item['IPAddr'], font=('蔚然雅黑', 10, 'bold'), fill='#C00000',
tags=item['IPAddr'])
elif item['ObjLable'] == 'R3':
self.cv.create_text(ObjX, ObjY-30, text=item['ObjLable'], font=('蔚然雅黑',16,'bold'),fill='#C00000', tags=item['ObjLable'])
elif item['ObjLable'] == 'B':
self.cv.create_text(ObjX+30, ObjY+10, text=item['ObjLable'], font=('蔚然雅黑',16,'bold'),fill='#C00000', tags=item['ObjLable'])
return None

@ -1,456 +0,0 @@
# 在这里实现移动信封并实现并在实现的同时使最下方和最右方的canvas中显示数据
import copy
import tkinter as tk
import time
from data_detail import Detail_Show, Show_green_detail
from data_crud_sqlite import *
# 建立全局变量
num_begin_x = 0
num_begin_y = 0
num_end_x = 1
num_end_y = 1
# 建立信封移动并处理输出数据的函数
class EnvelopMove():
def __init__(self,cv,img_host,img_router,img_envelop,img_detail,move_data,Objshow_data,AppPackTag_Data,
unpacket,move_number,right_on_text,right_under_text,under_text):
self.cv = cv # 主页面最大的canvas页面
self.unpacket = unpacket # 这是一个函数,暂时没用
self.img_host = img_host # 主机png图片
self.img_router = img_router # png图片
self.img_detail = img_detail # png图片
self.img_envelop = img_envelop # 信封的png图片
self.move_data = move_data # 信封的移动位置的数据集合 数据样式:[(229, 202, 'SH01', 1), (300, 300, 'SR01', 2)]
self.x1 = self.move_data[0][0] # 定义初始信封的x轴位置
self.y1 = self.move_data[0][1] # 定义初始信封的y轴位置
self.Begin_x = None # 定义一个用来存储移动数据的x轴值
self.End_y = None # 定义一个用来存储移动数据的y轴值
self.num_begin_x = 0 # 定义获取数组的第一个对比值
self.num_begin_x_2 = 0
self.num_begin_x_3 = 0 # 第三次
self.num_end_x = 1 # 定义获取数组的下一个对比值
self.num_end_x_2 = 1
self.num_end_x_3 = 1 # 第三次
self.num_begin_y = 0 # 定义获取数据下的固定位置值0
self.num_end_y = 1 # 定义获取数据下的固定位置值1
self.coord_Ture = True # 定义一个判断用来使用croods函数
self.move_number_frist = 1 # 定义一个移动数据的初始值
self.move_number_last = move_number # 数据为需要循环移动信封的次数 该数据为最后值
self.move_number_add = False # 定义一个值用来实现信封循环发送的判断值
self.move_number_add_2 = False # 第二次循环进入第三次
self.right_on_text = right_on_text # 发送主机文本框
self.right_under_text = right_under_text # 接收主机文本框
self.under_text = under_text # 连续信息数据文本框
self.Objshow_data = Objshow_data # 发送的数据总体信息
self.AppPackTag_Data = AppPackTag_Data # 输入数据总体
self.number_late = 0 # 设置循环输出的例子
self.number_late_1 = 0
self.number_late_2 = 0
self.one_print_1 = True # 判断是否为第一次输出
self.one_print_2 = True # 第二次
self.one_print_3 = True
self.last_envelop_number = int(self.AppPackTag_Data['AppPackSize']) % 2048
# 创建一个信封对象
def main_envelop(self):
'''在这个位置编写发送和接收文本框中的信息'''
data_Send_0 = '发送主机: '+self.Objshow_data[0]['ObjLable']+'\n'
data_Send_1 = 'IP地址: '+self.Objshow_data[0]['IPAddr']+'\n' # 发送主机详情第一行
data_Send_2 = 'Mac地址: '+self.Objshow_data[0]['MACAddr']+'\n' # 发送主机详情第二行
data_Send_3 = '发送数据包大小: '+self.AppPackTag_Data['AppPackSize']+'KB'+'\n' # 发送主机详情第三行
data_Send_4 = '已发送数据包数量: 0'+'\n' # 发送主机详情第四行
data_Send_5 = '需要发送的数据包总数: '+str(self.move_number_last)+'\n'
self.right_on_text.insert(tk.END, data_Send_0)
self.right_on_text.insert(tk.END, data_Send_1)
self.right_on_text.insert(tk.END, data_Send_2)
self.right_on_text.insert(tk.END, data_Send_3)
self.right_on_text.insert(tk.END, data_Send_4)
self.right_on_text.insert(tk.END, data_Send_5)
data_Req_1 = '接收主机: '+self.Objshow_data[-1]['ObjLable']+'\n'
data_Req_2 = 'IP地址: '+self.Objshow_data[-1]['IPAddr']+'\n'
data_Req_3 = 'Mac地址: '+self.Objshow_data[-1]['MACAddr']+'\n'
data_Req_4 = '接收数据包大小: '+self.AppPackTag_Data['AppPackSize']+'KB'+'\n'
data_Req_5 = '已接收的数据包数量: 0'+'\n'
data_Req_6 = '需要接收的数据包总数: '+str(self.move_number_last)+'\n'
self.right_under_text.insert(tk.END, data_Req_1)
self.right_under_text.insert(tk.END, data_Req_2)
self.right_under_text.insert(tk.END, data_Req_3)
self.right_under_text.insert(tk.END, data_Req_4)
self.right_under_text.insert(tk.END, data_Req_5)
self.right_under_text.insert(tk.END, data_Req_6)
self.envelop_1 = self.cv.create_image(self.x1, self.y1, image=self.img_envelop,tags='envelop') # 在初始位置创建一个信封图标
self.show_data_move()
if self.move_number_last >= 2:
self.envelop_2 = self.cv.create_image(self.x1, self.y1, image=self.img_envelop,tags='envelop')
if self.move_number_last >= 3:
self.envelop_3 = self.cv.create_image(self.x1, self.y1, image=self.img_envelop,tags='envelop')
return None
# 类似建立模拟函数,第一步先建立信封显示
def show_data_move(self):
'''在这个位置添加一个判断用来设置新的envelop ?暂时存疑'''
if self.coord_Ture:
self.x_1, self.y_1 = self.cv.coords(self.envelop_1)
# print(self.x_1,self.y_1)
if self.one_print_1:
s_index = '5.10'
e_index = '5.11'
self.right_on_text.delete(s_index, e_index)
self.right_on_text.insert(e_index, '1')
data_one_1 = '发送主机:'+self.Objshow_data[0]['ObjLable']+'\n' # 第一次发送主机
data_one_2 = '接收主机: '+self.Objshow_data[-1]['ObjLable']+'\n' # 第二行
data_one_3 = '数据包大小: '+self.AppPackTag_Data['AppPackSize']+'KB'+'\n' # 第三行
self.one_print_1 = False
if self.num_end_x <= (len(self.move_data)-1):
# self.Begin_x 为需要x轴移动的距离
Begin_x = self.move_data[self.num_end_x][self.num_begin_y]-self.move_data[self.num_begin_x][self.num_begin_y]
# self.End_y 为需要y轴移动的距离
End_y = self.move_data[self.num_end_x][self.num_end_y]-self.move_data[self.num_begin_x][self.num_end_y]
# 移动信封
self.cv.move(self.envelop_1, Begin_x/100, End_y/100)
if int(self.move_data[self.num_end_x][self.num_begin_y]) - 2 <= self.x_1 <= int(
self.move_data[self.num_end_x][self.num_begin_y]) + 2 and int(
self.move_data[self.num_end_x][self.num_end_y]) - 2 <= self.y_1 <= int(
self.move_data[self.num_end_x][self.num_end_y]) + 2:
time.sleep(1)
self.num_begin_x = self.num_begin_x + 1
self.num_end_x = self.num_end_x + 1
self.move_number_add = True
data_late_1 = '发送对象: '+self.Objshow_data[self.number_late]['ObjLable']+'\n'
data_late_1_1 = '发送对象IP地址: '+self.Objshow_data[self.number_late]['IPAddr']+'\n'
data_late_1_2 = '发送对象Mac地址: '+self.Objshow_data[self.number_late]['MACAddr']+'\n'
data_late_1_3 = '数据包对象: '+'1'+' / '+str(self.move_number_last)+'\n'
if self.move_number_last == 1:
data_late_1_4 = '数据包大小: '+str(self.last_envelop_number)+' KB \n'
else:
data_late_1_4 = '数据包大小: '+'2048 KB \n'
data_late_1_5 = '数据解包中...... \n'
data_late_1_6 = '数据解包完成 \n'
data_late_2 = '接收对象:'+self.Objshow_data[self.number_late+1]['ObjLable']+'\n'
data_late_2_1 = '接收对象IP地址: '+self.Objshow_data[self.number_late+1]['IPAddr']+'\n'
data_late_2_2 = '接收对象Mac地址: '+self.Objshow_data[self.number_late+1]['MACAddr']+'\n'
data_late_2_3 = '数据封包中...... \n'
data_late_2_4 = '数据封包完成 \n'
self.under_text.insert(tk.END, '*' * 15 + '第一个数据包信息' + '*' * 15 + '\n')
self.under_text.insert(tk.END, data_late_1)
self.under_text.insert(tk.END, data_late_1_1)
self.under_text.insert(tk.END, data_late_1_2)
self.under_text.insert(tk.END, data_late_1_3)
self.under_text.insert(tk.END, data_late_1_4)
self.under_text.insert(tk.END, data_late_1_5)
self.under_text.insert(tk.END, data_late_1_6)
self.under_text.insert(tk.END, data_late_2)
self.under_text.insert(tk.END, data_late_2_1)
self.under_text.insert(tk.END, data_late_2_2)
self.under_text.insert(tk.END, data_late_2_3)
self.under_text.insert(tk.END, data_late_2_4)
self.number_late += 1
self.cv.after(12, self.show_data_move)
if self.move_number_add and self.move_number_last >= 2:
self.show_data_move_2()
elif self.num_end_x == len(self.move_data):
self.start_index = "5.11"
self.end_index = "5.12"
self.right_under_text.delete(self.start_index, self.end_index)
self.right_under_text.insert(self.end_index, '1')
if self.move_number_last == 1:
self.cv.delete('envelop')
self.coord_Ture = False
self.detail_data = Detail_Show(cv=self.cv, img_detail=self.img_detail, move_data=self.move_data).show_detail()
return None
# 建立移动第二个信封的函数
def show_data_move_2(self):
if self.coord_Ture:
self.x_2, self.y_2 = self.cv.coords(self.envelop_2)
if self.one_print_2:
s_index = '5.10'
e_index = '5.11'
self.right_on_text.delete(s_index, e_index)
self.right_on_text.insert(e_index, '2')
self.one_print_2 = False
if self.num_end_x_2 <= (len(self.move_data) - 1):
# self.Begin_x 为需要x轴移动的距离
Begin_x = self.move_data[self.num_end_x_2][self.num_begin_y] - self.move_data[self.num_begin_x_2][
self.num_begin_y]
# self.End_y 为需要y轴移动的距离
End_y = self.move_data[self.num_end_x_2][self.num_end_y] - self.move_data[self.num_begin_x_2][
self.num_end_y]
# 移动信封
self.cv.move(self.envelop_2, Begin_x / 100, End_y / 100)
if int(self.move_data[self.num_end_x_2][self.num_begin_y]) - 2 <= self.x_2 <= int(
self.move_data[self.num_end_x_2][self.num_begin_y]) + 2 and int(
self.move_data[self.num_end_x_2][self.num_end_y]) - 2 <= self.y_2 <= int(
self.move_data[self.num_end_x_2][self.num_end_y]) + 2:
# time.sleep(0.1)
self.num_begin_x_2 = self.num_begin_x_2 + 1
self.num_end_x_2 = self.num_end_x_2 + 1
self.move_number_add_2 = True # 当第二个信封进入到第二个节点时,将数据进入到第三个
'''在这里添加一段输出数据试试判断试试'''
self.under_text.insert(tk.END, '#' * 15 + '第二个数据包信息' + '#' * 15 + '\n')
data_late_1 = '发送对象: ' + self.Objshow_data[self.number_late_1]['ObjLable'] + '\n'
data_late_1_1 = '发送对象IP地址: ' + self.Objshow_data[self.number_late_1]['IPAddr'] + '\n'
data_late_1_2 = '发送对象Mac地址: ' + self.Objshow_data[self.number_late_1]['MACAddr'] + '\n'
data_late_1_3 = '数据包对象: ' + '2' + ' / ' + str(self.move_number_last) + '\n'
if self.move_number_last == 2:
data_late_1_4 = '数据包大小: ' + str(self.last_envelop_number) + ' KB \n'
else:
data_late_1_4 = '数据包大小: ' + '2048 KB \n'
data_late_1_5 = '数据解包中...... \n'
data_late_1_6 = '数据解包完成 \n'
data_late_2 = '接收对象:' + self.Objshow_data[self.number_late_1 + 1]['ObjLable'] + '\n'
data_late_2_1 = '接收对象IP地址: ' + self.Objshow_data[self.number_late_1 + 1]['IPAddr'] + '\n'
data_late_2_2 = '接收对象Mac地址: ' + self.Objshow_data[self.number_late_1 + 1]['MACAddr'] + '\n'
data_late_2_3 = '数据封包中...... \n'
data_late_2_4 = '数据封包完成 \n'
self.under_text.insert(tk.END, data_late_1)
self.under_text.insert(tk.END, data_late_1_1)
self.under_text.insert(tk.END, data_late_1_2)
self.under_text.insert(tk.END, data_late_1_3)
self.under_text.insert(tk.END, data_late_1_4)
self.under_text.insert(tk.END, data_late_1_5)
self.under_text.insert(tk.END, data_late_1_6)
self.under_text.insert(tk.END, data_late_2)
self.under_text.insert(tk.END, data_late_2_1)
self.under_text.insert(tk.END, data_late_2_2)
self.under_text.insert(tk.END, data_late_2_3)
self.under_text.insert(tk.END, data_late_2_4)
self.number_late_1 += 1
if self.num_end_x_2 == 5:
self.cv.after(12, self.show_data_move_2)
# time.sleep(1)
if self.move_number_add_2 and self.move_number_last>=3:
self.show_data_move_3()
elif self.num_end_x_2 == len(self.move_data):
self.right_under_text.delete(self.start_index, self.end_index)
self.right_under_text.insert(self.end_index, '2')
if self.move_number_last == 2:
self.cv.delete('envelop')
self.coord_Ture = False
self.detail_data = Detail_Show(cv=self.cv, img_detail=self.img_detail, move_data=self.move_data).show_detail()
return None
# 建立移动第三个信封的函数
def show_data_move_3(self):
if self.coord_Ture:
self.x_3, self.y_3 = self.cv.coords(self.envelop_3)
if self.one_print_3:
s_index = '5.10'
e_index = '5.11'
self.right_on_text.delete(s_index, e_index)
self.right_on_text.insert(e_index, '3')
self.one_print_3 = False
if self.num_end_x_3 <= (len(self.move_data) - 1):
# self.Begin_x 为需要x轴移动的距离
Begin_x = self.move_data[self.num_end_x_3][self.num_begin_y] - self.move_data[self.num_begin_x_3][
self.num_begin_y]
# self.End_y 为需要y轴移动的距离
End_y = self.move_data[self.num_end_x_3][self.num_end_y] - self.move_data[self.num_begin_x_3][
self.num_end_y]
# 移动信封
self.cv.move(self.envelop_3, Begin_x / 100, End_y / 100)
if int(self.move_data[self.num_end_x_3][self.num_begin_y]) - 2 <= self.x_3 <= int(
self.move_data[self.num_end_x_3][self.num_begin_y]) + 2 and int(
self.move_data[self.num_end_x_3][self.num_end_y]) - 2 <= self.y_3 <= int(
self.move_data[self.num_end_x_3][self.num_end_y]) + 2:
# time.sleep(0.1)
self.num_begin_x_3 = self.num_begin_x_3 + 1
self.num_end_x_3 = self.num_end_x_3 + 1
self.under_text.insert(tk.END, '*' * 15 + '第三个数据包信息' + '*' * 15 + '\n')
data_late_1 = '发送对象: ' + self.Objshow_data[self.number_late_2]['ObjLable'] + '\n'
data_late_1_1 = '发送对象IP地址: ' + self.Objshow_data[self.number_late_2]['IPAddr'] + '\n'
data_late_1_2 = '发送对象Mac地址: ' + self.Objshow_data[self.number_late_2]['MACAddr'] + '\n'
data_late_1_3 = '数据包对象: ' + '2' + ' / ' + str(self.move_number_last) + '\n'
if self.move_number_last ==3 :
data_late_1_4 = '数据包大小: ' + str(self.last_envelop_number) + ' KB \n'
else:
data_late_1_4 = '数据包大小: ' + '2048 KB \n'
data_late_1_5 = '数据解包中...... \n'
data_late_1_6 = '数据解包完成 \n'
data_late_2 = '接收对象:' + self.Objshow_data[self.number_late_2 + 1]['ObjLable'] + '\n'
data_late_2_1 = '接收对象IP地址: ' + self.Objshow_data[self.number_late_2 + 1]['IPAddr'] + '\n'
data_late_2_2 = '接收对象Mac地址: ' + self.Objshow_data[self.number_late_2 + 1]['MACAddr'] + '\n'
data_late_2_3 = '数据封包中...... \n'
data_late_2_4 = '数据封包完成 \n'
self.under_text.insert(tk.END, data_late_1)
self.under_text.insert(tk.END, data_late_1_1)
self.under_text.insert(tk.END, data_late_1_2)
self.under_text.insert(tk.END, data_late_1_3)
self.under_text.insert(tk.END, data_late_1_4)
self.under_text.insert(tk.END, data_late_1_5)
self.under_text.insert(tk.END, data_late_1_6)
self.under_text.insert(tk.END, data_late_2)
self.under_text.insert(tk.END, data_late_2_1)
self.under_text.insert(tk.END, data_late_2_2)
self.under_text.insert(tk.END, data_late_2_3)
self.under_text.insert(tk.END, data_late_2_4)
self.number_late_2 += 1
if self.num_end_x_3 == 5:
# time.sleep(1)
self.cv.after(12, self.show_data_move_3)
elif self.num_end_x_3 == len(self.move_data):
self.right_under_text.delete(self.start_index, self.end_index)
self.right_under_text.insert(self.end_index, '3')
if self.move_number_last == 3:
self.cv.delete('envelop')
self.coord_Ture = False
self.detail_data = Detail_Show(cv=self.cv, img_detail=self.img_detail, move_data=self.move_data).show_detail()
return None
# 在这里创建鼠标左键点击详情头位置显示数据
def show_detail_all(self, event):
frist_X = event.x
frist_y = event.y
for item in self.detail_data:
if frist_X-10<item[0]<frist_X+10 and frist_y-10<item[1]<frist_y+10:
Show_green_detail(cv=self.cv, item=item).draw_detail()
else:
pass
return None
# 创建鼠标点击事件
def Mouse_Event(self):
Mouse = self.cv.bind("<Button-1>", self.show_detail_all) # 点击鼠标左键触发显示数据函数
return Mouse
# 创建修改objshow列的函数
def revise_objshow(send_host, reception_host):
'''在这个位置判断发送主机和接收主机的位置并修改其数据'''
if send_host == 'A':
if reception_host == 'B':
# 调用函数修改objshow列为 0
reve_objshow()
# 建立一个经过对象的数组
after_data = ['A', 'R1', 'B']
# 调用函数reve_after来给对象重新赋值
reve_after(after_data)
'''后面可能需要在建立一个重组对象数组的功能'''
elif reception_host == 'C':
reve_objshow()
after_data = ['A', 'R1', 'R2', 'R4', 'R5', 'C']
reve_after(after_data)
elif reception_host == 'D':
reve_objshow()
after_data = ['A', 'R1', 'R2', 'R4', 'R5', 'D']
reve_after(after_data)
elif send_host == 'B':
if reception_host == 'A':
reve_objshow()
after_data = ['B', 'R1', 'A']
reve_after(after_data)
elif reception_host == 'C':
reve_objshow()
after_data = ['B', 'R1', 'R2', 'R4', 'R5', 'C']
reve_after(after_data)
elif reception_host == 'D':
reve_objshow()
after_data = ['B', 'R1', 'R2', 'R4', 'R5', 'C']
reve_after(after_data)
elif send_host == 'C':
if reception_host == 'A':
reve_objshow()
after_data = ['C', 'R5', 'R4', 'R2', 'R1', 'A']
reve_after(after_data)
elif reception_host == 'B':
reve_objshow()
after_data = ['C', 'R5', 'R4', 'R2', 'R1', 'A']
reve_after(after_data)
elif reception_host == 'D':
reve_objshow()
after_data = ['C', 'R5', 'D']
reve_after(after_data)
elif send_host == 'D':
if reception_host == 'A':
reve_objshow()
after_data = ['D', 'R5', 'R4', 'R2', 'R1', 'A']
reve_after(after_data)
elif reception_host == 'B':
reve_objshow()
after_data = ['D', 'R5', 'R4', 'R2', 'R1', 'B']
reve_after(after_data)
elif reception_host == 'C':
reve_objshow()
after_data = ['D', 'R5', 'C']
reve_after(after_data)
return after_data
# 将数组顺序倒换并返回倒序数组
def order_array(array, send_host, reception_host):
if send_host == 'D':
if reception_host == 'A':
array = array[::-1]
elif reception_host == 'B':
ObjID_reception = select_ObjLable_ObjID(reception_host)
ObjID_send = select_ObjLable_ObjID(send_host)
array = array[::-1]
for item in array:
if item == ObjID_send:
index_move_send = array.index(ObjID_send)
array = [ObjID_send]+array[:index_move_send]+array[index_move_send+1:]
elif item == ObjID_reception:
index_move_reception = array.index(ObjID_reception)
array = array[:index_move_reception]+array[index_move_reception+1:]+[ObjID_reception]
else:
pass
elif reception_host == 'C':
ObjID_send = select_ObjLable_ObjID(send_host)
for item in array:
if item == ObjID_send:
index_move_send = array.index(ObjID_send)
array = [ObjID_send]+array[:index_move_send]+array[index_move_send+1:]
else:
pass
elif send_host == 'C':
if reception_host == 'A':
array = array[::-1]
elif reception_host == 'B':
ObjID_reception = select_ObjLable_ObjID(reception_host)
ObjID_send = select_ObjLable_ObjID(send_host)
array = array[::-1]
for item in array:
if item == ObjID_send:
index_move_send = array.index(ObjID_send)
array = [ObjID_send] + array[:index_move_send] + array[index_move_send + 1:]
elif item == ObjID_reception:
index_move_reception = array.index(ObjID_reception)
array = array[:index_move_reception] + array[index_move_reception + 1:] + [ObjID_reception]
else:
pass
elif reception_host == 'D':
ObjID_send = select_ObjLable_ObjID(send_host)
for item in array:
if item == ObjID_send:
index_move_send = array.index(ObjID_send)
array = [ObjID_send] + array[:index_move_send] + array[index_move_send + 1:]
else:
pass
elif send_host == 'B':
if reception_host == 'A':
array = array[::-1]
elif reception_host == 'C' or reception_host == 'D':
ObjID_send = select_ObjLable_ObjID(send_host)
for item in array:
if item == ObjID_send:
index_move_send = array.index(ObjID_send)
array = [ObjID_send] + array[:index_move_send] + array[index_move_send + 1:]
else:
pass
return array
'''建立一个函数使获取信封循环次数并为每次添加编号'''
def add_number(number):
number_all = []
for i in range(0,number):
number = 'envelop_'+str(i+1)
number_all.append(number)
return number_all

@ -1,76 +0,0 @@
# 创建一个画线的类
class Line_Right():
def __init__(self, cv, line_data):
self.cv = cv
self.line_data = line_data
# 创建函数来画出需要的线
def line_test(self):
# 将数据通过循环取出,使用下标的形式
for i in range(0, len(self.line_data)):
'''需要进行判断下标i+1存在数据'''
if i + 1 != len(self.line_data):
x = self.line_data[i]['ObjX']
y = self.line_data[i]['ObjY']
next_x = self.line_data[i + 1]['ObjX']
next_y = self.line_data[i + 1]['ObjY']
self.cv.create_line(x, y, next_x, next_y, width=3, fill='#5B9BD5')
# print(i)
return None
# 创建一个用于画出永久固定的无用的线的类
class Useless_line():
def __init__(self, cv, Useless_line_data):
self.cv = cv
self.Useless_line_data = Useless_line_data
# 创建函数用来画出线
def draw_line_less(self):
data_all_zero = self.data_handle()
# 通过循环判断获取的对象是谁,在给该对象画出线条
for item in data_all_zero:
# 在这里添加判断
if item['ID'] == 7: # 这个以后换一个判断信息
# 在这里画出线
self.cv.create_line(item['ObjX'],item['ObjY'],250,160,width=3, fill='#00B050')
if item['ID'] == 8:
# 在这里画出连接三条线
self.cv.create_line(item['ObjX'],item['ObjY'],370,130,width=1, fill='#5B9BD5')
self.cv.create_line(item['ObjX'], item['ObjY'], 400, 200, width=1, fill='#5B9BD5')
self.cv.create_line(item['ObjX'], item['ObjY'], 480, 260, width=1, fill='#5B9BD5')
if item['ID'] == 9:
self.cv.create_line(item['ObjX'], item['ObjY'], 480, 260, width=2, fill='#5B9BD5')
return None
# 建立函数用来处理获取的数据
def data_handle(self):
data_ObjShow_zero_all = []
for item in self.Useless_line_data:
# print(item)
if item['ObjShow'] == 0:
# print(item)
data_ObjShow_zero_all.append(item)
# print(data_ObjShow_zero_all)
return data_ObjShow_zero_all
# 对获取的line_data进行处理
def line_draw(ShowData):
line_data_all = [] # 定义一个数组用来存储所有数据
# 将获取的数据循环获取需要的数据
for item in ShowData:
# print(item)
ObjX = item['ObjX']
ObjY = item['ObjY']
line_data = {
'ObjX': ObjX,
'ObjY': ObjY
}
line_data_all.append(line_data)
# print(line_data_all)
return line_data_all

@ -1,157 +0,0 @@
# 建立一个函数用来判断封包数据的正确性
'''
在这里编写数据包正误判断
在这里引入数据
test: 先使用自身对比判断出错误环节or与下一层产生的数据对比是否出错
判断是否要写成一个函数呢在数据处理函数中直接判断会不会好一点呢
目前想法是先判断自己吧
自己进行判断的话则不需要额外写外接函数
TRUE == 对自身获取的地址进行判断正误判断格式
'''
import re
# 定义一个正则表达式来判断ip地址的格式是否正确
zz_ip = '^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$'
zz_mac = '([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})'
compile_ip = re.compile(zz_ip)
compile_mac = re.compile(zz_mac)
# 判断是否符合ip地址格式要求
def Judgement_Zz_IP(IP_Data):
if compile_ip.match(IP_Data):
return True
else:
return False
def Judgement_Zz_MAC(MAC_Data):
if compile_mac.match(MAC_Data):
return True
else:
return False
# 判断AppData数据正误,地址是否存在,判断格式.
def Judgement_AppData(SourceAppAddr, TargetAppAddr):
'''
在这里添加判断数据正确性的代码 备注test 目前
不知道需要对比的数据是啥所以先对比自身
不建议使用for循环可以使用if嵌套
'''
# 将获取的数据进行切割
SourceAppAddr = SourceAppAddr.split(':')[0]
TargetAppAddr = TargetAppAddr.split(':')[0]
# print(SourceAppAddr)
source = Judgement_Zz_IP(SourceAppAddr) # 发出数据IP判断
if source != True:
print('SourceIP地址格式错误')
target = Judgement_Zz_IP(TargetAppAddr) # 接收数据IP判断
if target != True:
print('TargetIP地址格式错误')
return None
# 判断TransData数据正误 判断地址是否与上级地址是都一样。是否存在,外加判断端口号是否符合要求是否存在
def Judgement_TransData(Old_SourceAppAddr,Old_TargetAppAddr,New_SourceAppAddr,New_TargetAppAddr,SentPort,RpctPort):
'''
在这里添加判断数据正确性的代码 备注test 目前
不知道需要对比的数据是啥所以先对比自身
不建议使用for循环可以使用if嵌套
'''
# 先判断地址是否符合格式在进行比较,先进行字符串的切割
Old_SourceAppAddr = Old_SourceAppAddr.split(':')[0]
Old_TargetAppAddr = Old_TargetAppAddr.split(':')[0]
New_SourceAppAddr = New_SourceAppAddr.split(':')[0]
New_TargetAppAddr = New_TargetAppAddr.split(':')[0]
new_source = Judgement_Zz_IP(New_SourceAppAddr)
new_target = Judgement_Zz_IP(New_TargetAppAddr)
if new_source:
if Old_SourceAppAddr != New_SourceAppAddr:
print('新地址与原地址不相同')
else:
print('SourceIP地址格式错误')
if new_target:
if Old_TargetAppAddr != New_TargetAppAddr:
print('新地址与原地址不相同')
else:
print('TargetIP地址格式错误')
# 判断端口号是否符合要求
if SentPort < 2048 or SentPort > 65535:
print('端口号不符合格式')
if RpctPort< 2048 or RpctPort > 65535:
print('端口号不符合格式')
return None
# 判断IPData数据正误
def Judgement_IPData(Old_SourceIP,Old_TargetIP,New_SourceIP,New_TargetIP):
'''
在这里添加判断数据正确性的代码 备注test 目前
不知道需要对比的数据是啥所以先对比自身
不建议使用for循环可以使用if嵌套
'''
new_sourceIP = Judgement_Zz_IP(New_SourceIP)
new_targetIP = Judgement_Zz_IP(New_TargetIP)
if new_sourceIP:
if Old_SourceIP != New_SourceIP:
print('新地址与原地址不相同')
else:
print('SourceIP地址格式错误')
if new_targetIP:
if Old_TargetIP != New_TargetIP:
print('新地址与原地址不相同')
else:
print('TargetIP地址格式错误')
return None
# 判断MACData数据正误
def Judgement_MACData(Old_SourceIP,Old_TargetIP,New_SourceIP,New_TargetIP,SentMAC,RcptMAC):
'''
在这里添加判断数据正确性的代码 备注test 目前
不知道需要对比的数据是啥所以先对比自身
不建议使用for循环可以使用if嵌套
'''
new_sourceIP = Judgement_Zz_IP(New_SourceIP)
new_targetIP = Judgement_Zz_IP(New_TargetIP)
if new_sourceIP:
if Old_SourceIP != New_SourceIP:
print('新地址与原地址不相同')
else:
print('SourceIP地址格式错误')
if new_targetIP:
if Old_TargetIP != New_TargetIP:
print('新地址与原地址不相同')
else:
print('TargetIP地址格式错误')
sentmac = Judgement_Zz_MAC(SentMAC)
rcptmac = Judgement_Zz_MAC(RcptMAC)
if sentmac != True:
print('SentMAC地址格式错误')
if rcptmac != True:
print('RcptMAC地址格式错误')
return None
if __name__ == '__main__':
# 在这里建立一组test数据用来比较
# test: 测试
# Judgement_AppData('SHO1','A','AppPack1',6144,'A-6144-Data','101.1.1.2:18010','201.21.1.2:18010',test_4)
# Judgement_TransData('ObjID','IDkey','TransPackID','TransSeq','TransTag','AppPackID','SentPort','RpctPort','SourceAppAddr','TargetAppAddr',TransPackedString)
# Judgement_IPData('ObjID','IDkey','IP_number','IPPackID','TransPackID','SourceIP','TargetIP','SourceAppAddr','TargetAppAddr',IPPackedString)
# Judgement_MACData('ObjID','IDkey','MAC_number','MacPackID','IPPackID','SentMAC','RcptMAC','SourceIP','TargetIP','SourceAppAddr','TargetAppAddr',MacPackedString)
ip_test = '127.0.0.1:18010'
ip_test2 = '196.168.2.1:18010'
ip_test_new = '196.168.1.1'
ip_test2_new = '196.168.3.1'
prot = 1395
prot_1 = 65555
test_mac = '00:1a:8c:10:ad:30'
test_mac1 = '10:00:00:90:fa:02:88:00'
# print(Judgement_Zz_IP(ip_test))
# Judgement_AppData(ip_test,ip_test2)
# Judgement_TransData(Old_SourceAppAddr=ip_test,Old_TargetAppAddr=ip_test2,New_SourceAppAddr=ip_test_new,New_TargetAppAddr=ip_test2_new,SentPort=prot,RpctPort=prot_1)
Judgement_MACData(Old_SourceIP=ip_test_new,Old_TargetIP=ip_test2_new,New_SourceIP=ip_test2_new,New_TargetIP=ip_test_new,SentMAC=test_mac,RcptMAC=test_mac1)

@ -1,189 +0,0 @@
# 这个函数用来实现模拟解包过程
# 创建类用来处理解包函数
class Unpack_All():
# 获取需要的数据
def __init__(self,MacPacketString, IPPacketString, TransPacketString, AppPacketString):
self.MacPacketString = MacPacketString
self.IPPacketString = IPPacketString
self.TransPacketString = TransPacketString
self.AppPacketString = AppPacketString
# 建立函数用来处理MacPacketString中的数据
def unpack_mac_data(self):
# print(self.MacPacketString)
MacData_All = []
# 将获取的数据分解成macdata中
for item in self.MacPacketString:
ObjID = item['ObjID']
ObjLable = item['ObjLable']
MacPackId = item['MacPackId']
IPPackID = item['IPPackID']
sentmac = item['sentmac']
rcptmac = item['rcptmac']
sourceip = item['sourceip']
targetip = item['targetip']
sourceAppAddr = item['sourceAppAddr']
targetAppAddr = item['targetAppAddr']
MacData = {
'ObjID': ObjID,
'ObjLable': ObjLable,
'MacPackId': MacPackId,
'IPPackID': IPPackID,
'sentmac': sentmac,
'rcptmac': rcptmac,
'sourceip': sourceip,
'targetip': targetip,
'sourceAppAddr': sourceAppAddr,
'targetAppAddr': targetAppAddr,
'MacPacketString': item
}
MacData_All.append(MacData)
return MacData_All
# 建立函数用来处理IPPacket中的数据
def unpack_ip_data(self):
IPData_All = []
for item in self.IPPacketString:
ObjID = item['ObjID']
ObjLable = item['ObjLable']
IPPackID = item['IPPackID']
TransPackID = item['TransPackID']
sourceip = item['sourceip']
targetip = item['targetip']
sourceAppAddr = item['sourceAppAddr']
targetAppAddr = item['targetAppAddr']
IPData = {
'ObjID': ObjID,
'ObjLable': ObjLable,
'IPPackID': IPPackID,
'TransPackID': TransPackID,
'sourceip': sourceip,
'targetip': targetip,
'sourceAppAddr': sourceAppAddr,
'targetAppAddr': targetAppAddr,
'IPPacketString': item
}
IPData_All.append(IPData)
return IPData_All
# 建立一个函数用来处理Trans的解包
def unpack_trans_data(self):
TransData_All = []
for item in self.TransPacketString:
ObjID = item['ObjID']
ObjLable = item['ObjLable']
TransPackID = item['TransPackID']
TransSeq = item['TransSeq']
TransTag = item['TransTag']
AppPackId = item['AppPackId']
sentport = item['sentport']
rpctport = item['rpctport']
sourceAppAddr = item['sourceAppAddr']
targetAppAddr = item['targetAppAddr']
TransData = {
'ObjID': ObjID,
'ObjLable': ObjLable,
'TransPackID': TransPackID,
'TransSeq': TransSeq,
'TransTag': TransTag,
'AppPackId': AppPackId,
'sentport': sentport,
'rpctport': rpctport,
'sourceAppAddr': sourceAppAddr,
'targetAppAddr': targetAppAddr,
'TransPacketString': item
}
TransData_All.append(TransData)
return TransData_All
# 建立一个函数用来处理App的解包
def unpack_app_data(self):
ObjID = self.AppPacketString['ObjID']
ObjLable = self.AppPacketString['ObjLable']
AppPackId = self.AppPacketString['AppPackId']
AppPackSize = self.AppPacketString['AppPackSize']
AppPackTag = self.AppPacketString['AppPackTag']
sourceAppAddr = self.AppPacketString['sourceAppAddr']
targetAppAddr = self.AppPacketString['targetAppAddr']
AppData = {
'ObjID': ObjID,
'ObjLable': ObjLable,
'AppPackId': AppPackId,
'AppPackSize': AppPackSize,
'AppPackTag': AppPackTag,
'sourceAppAddr': sourceAppAddr,
'targetAppAddr': targetAppAddr,
'AppPacketString': self.AppPacketString
}
# print(AppData)
return AppData
if __name__ == '__main__':
MacPacketString = [
{'ObjID': 'SHO1',
'ObjLable': 'A',
'MAC_number': 1,
'MacPackId': 'MacPackID1',
'IPPackID': 'IPPack1',
'sentmac': '00:1a:8c:10:ad:30',
'rcptmac': '00:1a:8c:10:ad:20',
'sourceip': '196.168.1.1',
'targetip': '196.168.3.1',
'sourceAppAddr': '196.168.1.1:63179',
'targetAppAddr': '196.168.3.1:17242'
}]
IPPacketString = [
{'ObjID': 'SHO1',
'ObjLable': 'A',
'number': 1,
'IPPackID': 'IPPack1',
'TransPackID': 'TransPack1',
'sourceip': '196.168.1.1',
'targetip': '196.168.3.1',
'sourceAppAddr': '196.168.1.1:37486',
'targetAppAddr': '196.168.3.1:13191',
'Mac_data': '00:1a:8c:10:ad:30'}]
TransPacketString = [
{'ObjID': 'SHO1',
'ObjLable': 'A',
'TransPackID': 'TransPack1',
'TransSeq': '1',
'TransTag': 'A1',
'AppPackId': '1',
'sentport': '41749',
'rpctport': '20712',
'sourceAppAddr': '196.168.1.1:41749',
'targetAppAddr': '196.168.3.1:20712',
'timestamp': '15:25:59',
'Mac_data': '00:1a:8c:10:ad:30'}]
AppPacketString = {
'ObjID': 'SHO1',
'ObjLable': 'A',
'AppPackId': '1',
'AppPackSize': 1,
'AppPackTag': '1',
'sourceAppAddr': '196.168.1.1:47325',
'timeStamp': '15:22:28',
'Mac_data': '00:1a:8c:10:ad:30',
'targetAppAddr': '196.168.3.1:14035'}
test_line = Unpack_All(MacPacketString,IPPacketString,TransPacketString,AppPacketString)
# test_line.unpack_mac_data()
test = test_line.unpack_app_data()
print(test)
print(test_line.unpack_trans_data())
print(test_line.unpack_ip_data())
print(test_line.unpack_mac_data())
'''
{'ObjID': 'SHO1', 'ObjLable': 'A', 'AppPackId': '1', 'AppPackSize': 1, 'AppPackTag': '1', 'sourceAppAddr': '196.168.1.1:47325', 'targetAppAddr': '196.168.3.1:14035', 'AppPacketString': {'ObjID': 'SHO1', 'ObjLable': 'A', 'AppPackId': '1', 'AppPackSize': 1, 'AppPackTag': '1', 'sourceAppAddr': '196.168.1.1:47325', 'timeStamp': '15:22:28', 'Mac_data': '00:1a:8c:10:ad:30', 'targetAppAddr': '196.168.3.1:14035'}}
[{'ObjID': 'SHO1', 'ObjLable': 'A', 'TransPackID': 'TransPack1', 'TransSeq': '1', 'TransTag': 'A1', 'AppPackId': '1', 'sentport': '41749', 'rpctport': '20712', 'sourceAppAddr': '196.168.1.1:41749', 'targetAppAddr': '196.168.3.1:20712', 'TransPacketString': {'ObjID': 'SHO1', 'ObjLable': 'A', 'TransPackID': 'TransPack1', 'TransSeq': '1', 'TransTag': 'A1', 'AppPackId': '1', 'sentport': '41749', 'rpctport': '20712', 'sourceAppAddr': '196.168.1.1:41749', 'targetAppAddr': '196.168.3.1:20712', 'timestamp': '15:25:59', 'Mac_data': '00:1a:8c:10:ad:30'}}]
[{'ObjID': 'SHO1', 'ObjLable': 'A', 'IPPackID': 'IPPack1', 'TransPackID': 'TransPack1', 'sourceip': '196.168.1.1', 'targetip': '196.168.3.1', 'sourceAppAddr': '196.168.1.1:37486', 'targetAppAddr': '196.168.3.1:13191', 'IPPacketString': {'ObjID': 'SHO1', 'ObjLable': 'A', 'number': 1, 'IPPackID': 'IPPack1', 'TransPackID': 'TransPack1', 'sourceip': '196.168.1.1', 'targetip': '196.168.3.1', 'sourceAppAddr': '196.168.1.1:37486', 'targetAppAddr': '196.168.3.1:13191', 'Mac_data': '00:1a:8c:10:ad:30'}}]
[{'ObjID': 'SHO1', 'ObjLable': 'A', 'MacPackId': 'MacPackID1', 'IPPackID': 'IPPack1', 'sentmac': '00:1a:8c:10:ad:30', 'rcptmac': '00:1a:8c:10:ad:20', 'sourceip': '196.168.1.1', 'targetip': '196.168.3.1', 'sourceAppAddr': '196.168.1.1:63179', 'targetAppAddr': '196.168.3.1:17242', 'MacPacketString': {'ObjID': 'SHO1', 'ObjLable': 'A', 'MAC_number': 1, 'MacPackId': 'MacPackID1', 'IPPackID': 'IPPack1', 'sentmac': '00:1a:8c:10:ad:30', 'rcptmac': '00:1a:8c:10:ad:20', 'sourceip': '196.168.1.1', 'targetip': '196.168.3.1', 'sourceAppAddr': '196.168.1.1:63179', 'targetAppAddr': '196.168.3.1:17242'}}]
'''

@ -1,285 +0,0 @@
# 封包处理函数
import random
import datetime
# 建立一个类将所有的函数放入其中
# 将所有的主机路由器详细数据存入一个字典列表中?
# 将主机路由器的ObjID存入一个数组中通过循环来判断下一级的RctpMAC.
# MACID = ['MacA','MacR1', 'MacR2', 'MacR4', 'MacR5', 'MacD']
# 不能将所有的函数整合成一个类
# 建立一个全局变量IP_number
IP_number = 0
MAC_number = 0
class AllData():
'''
MACID: 这个数据将从数据库simhost获取所有的数据并将每条数据中以先后组成一个mac地址数组
ShowData 这个数据是将数据库simhost中的所有数据组成一个字典数组从里面
AppPackTag: 这个数据是需要用户点击前端页面的封包模拟里面输入的数据
'''
def __init__(self, MACID, ShowData, AppPackTag_Data):
self.MACID = MACID
self.ShowData = ShowData
self.AppPackTag_Data = AppPackTag_Data
def AppData(self):
MACID = self.MACID
ShowData = self.ShowData
AppPackTag_Data = self.AppPackTag_Data
# 拿到前台传过来的数据并处理
# 将收集的数据进行处理
'''
test:
这里添加一个对字典列表ShowData的for循环
然后对字典列表里的['ObjID']进行判断判断是否为开始主机
'''
# print(len(ShowData))
AppPackedString = {}
for i in range(0,len(ShowData)):
# print(i)
if i == 0 and ShowData[i]['ObjType'] == 1:
ObjID = ShowData[i]['ObjID']
ObjLable = ShowData[i]['ObjLable']
AppPackId = AppPackTag_Data['AppPackID']
AppPackSize = AppPackTag_Data['AppPackSize']
AppPackTag = AppPackTag_Data['AppPackTag']
sentport = random.randint(2048, 65535)
sourceAppAddr = ShowData[i]['IPAddr'] + ':' + str(sentport)
timeStamp = datetime.datetime.now().strftime('%H:%M:%S')
Mac_data = ShowData[i]['MACAddr']
# 对字典进行添加
AppPackedString['ObjID'] = ObjID
AppPackedString['ObjLable'] = ObjLable
AppPackedString['AppPackId'] = AppPackId
AppPackedString['AppPackSize'] = AppPackSize
AppPackedString['AppPackTag'] = AppPackTag
AppPackedString['sourceAppAddr'] = sourceAppAddr
AppPackedString['timeStamp'] = timeStamp
AppPackedString['Mac_data'] = Mac_data
if i == (len(ShowData)-1):
rpctport = random.randint(2048, 65535)
targetAppAddr = ShowData[i]['IPAddr'] + ':' + str(rpctport)
AppPackedString['targetAppAddr'] = targetAppAddr
return AppPackedString
def TransData(self,AppPackedString):
'''
这里需要处理获取的信息
'''
# print(AppPackedString)
AppPackSize = AppPackedString['AppPackSize']
page_true = Spilt_AppData(AppPackSize)
# 定义一个空列表存放所有TransPackedString
TransPackedString_All = []
# 将数据包分为page_true个传输层数据包
for i in range(0, page_true):
num = i + 1
# 这里需要建立一个将Trans数据封包函数
TransPackedString = insert_TransData(num, AppPackedString)
TransPackedString_All.append(TransPackedString)
# print(TransPackedString_All)
return TransPackedString_All
# 这里建立一个IP层封包数据函数
def IPData(self,TransPackedString):
# 将获取的字典数组进行拆分
IPPackedString_All = []
for item in TransPackedString:
global IP_number
IP_number = IP_number + 1 # IP_number为记录数据经过函数IPData的次数
ObjID = item['ObjID']
ObjLable = item['ObjLable']
IPPackID = 'IPPack' + str(IP_number)
TransPackID = item['TransPackID']
sourceip_true = item['sourceAppAddr'].split(':')
sourceip = sourceip_true[0]
targetip_true = item['targetAppAddr'].split(':')
targetip = targetip_true[0]
sourceAppAddr = item['sourceAppAddr']
targetAppAddr = item['targetAppAddr']
Mac_data = item['Mac_data']
IPPackedString = {
'ObjID': ObjID,
'ObjLable': ObjLable,
'number': IP_number,
'IPPackID': IPPackID,
'TransPackID': TransPackID,
'sourceip': sourceip,
'targetip': targetip,
'sourceAppAddr': sourceAppAddr,
'targetAppAddr': targetAppAddr,
'Mac_data': Mac_data
}
IPPackedString_All.append(IPPackedString)
return IPPackedString_All
'''{'ObjID': 'SHO1', 'ObjLable': 'A', 'AppPackId': 'AppPack1', 'AppPackSize': 6144, 'AppPackTag': 'A-6144-Data', 'sourceAppAddr': '196.168.1.1:35239', 'timeStamp': '13:03:25', 'Mac_data': '00:1a:8c:10:ad:30', 'targetAppAddr': '196.168.3.1:45771'}
[{'ObjID': 'SHO1', 'ObjLable': 'A', 'TransPackID': 'TransPack1', 'TransSeq': '1', 'TransTag': 'A1', 'AppPackId': 'AppPack1', 'sentport': '35239', 'rpctport': '45771', 'sourceAppAddr': '196.168.1.1:35239', 'targetAppAddr': '196.168.3.1:45771', 'timestamp': '13:03:25', 'Mac_data': '00:1a:8c:10:ad:30'}, {'ObjID': 'SHO1', 'ObjLable': 'A', 'TransPackID': 'TransPack2', 'TransSeq': '2', 'TransTag': 'A2', 'AppPackId': 'AppPack1', 'sentport': '35239', 'rpctport': '45771', 'sourceAppAddr': '196.168.1.1:35239', 'targetAppAddr': '196.168.3.1:45771', 'timestamp': '13:03:25', 'Mac_data': '00:1a:8c:10:ad:30'}, {'ObjID': 'SHO1', 'ObjLable': 'A', 'TransPackID': 'TransPack3', 'TransSeq': '3', 'TransTag': 'A3', 'AppPackId': 'AppPack1', 'sentport': '35239', 'rpctport': '45771', 'sourceAppAddr': '196.168.1.1:35239', 'targetAppAddr': '196.168.3.1:45771', 'timestamp': '13:03:25', 'Mac_data': '00:1a:8c:10:ad:30'}]
[{'ObjID': 'SHO1', 'ObjLable': 'A', 'number': 1, 'IPPackID': 'IPPack1', 'TransPackID': 'TransPack1', 'sourceip': '196.168.1.1', 'targetip': '196.168.3.1', 'sourceAppAddr': '196.168.1.1:35239', 'targetAppAddr': '196.168.3.1:45771', 'Mac_data': '00:1a:8c:10:ad:30'}, {'ObjID': 'SHO1', 'ObjLable': 'A', 'number': 2, 'IPPackID': 'IPPack2', 'TransPackID': 'TransPack2', 'sourceip': '196.168.1.1', 'targetip': '196.168.3.1', 'sourceAppAddr': '196.168.1.1:35239', 'targetAppAddr': '196.168.3.1:45771', 'Mac_data': '00:1a:8c:10:ad:30'}, {'ObjID': 'SHO1', 'ObjLable': 'A', 'number': 3, 'IPPackID': 'IPPack3', 'TransPackID': 'TransPack3', 'sourceip': '196.168.1.1', 'targetip': '196.168.3.1', 'sourceAppAddr': '196.168.1.1:35239', 'targetAppAddr': '196.168.3.1:45771', 'Mac_data': '00:1a:8c:10:ad:30'}]
[{'ObjID': 'SHO1', 'ObjLable': 'A', 'MAC_number': 1, 'MacPackId': 'MacPackID1', 'IPPackID': 'IPPack1', 'sentmac': '00:1a:8c:10:ad:30', 'rcptmac': '00:1a:8c:10:ad:30', 'sourceip': '196.168.1.1', 'targetip': '196.168.3.1', 'sourceAppAddr': '196.168.1.1:35239', 'targetAppAddr': '196.168.3.1:45771'}, {'ObjID': 'SHO1', 'ObjLable': 'A', 'MAC_number': 2, 'MacPackId': 'MacPackID2', 'IPPackID': 'IPPack2', 'sentmac': '00:1a:8c:10:ad:30', 'rcptmac': '00:1a:8c:10:ad:30', 'sourceip': '196.168.1.1', 'targetip': '196.168.3.1', 'sourceAppAddr': '196.168.1.1:35239', 'targetAppAddr': '196.168.3.1:45771'}, {'ObjID': 'SHO1', 'ObjLable': 'A', 'MAC_number': 3, 'MacPackId': 'MacPackID3', 'IPPackID': 'IPPack3', 'sentmac': '00:1a:8c:10:ad:30', 'rcptmac': '00:1a:8c:10:ad:30', 'sourceip': '196.168.1.1', 'targetip': '196.168.3.1', 'sourceAppAddr': '196.168.1.1:35239', 'targetAppAddr': '196.168.3.1:45771'}]
'''
# 这里建立一个MAC层封包数据函数
# def MACData(self,IPPackedString,MACID):
def MACData(self, IPPackedString):
# 建立一个空数组用来存放所有的数据
MacPackedString_All = []
for item in IPPackedString:
global MAC_number
rcptmac = ''
ObjID = item['ObjID']
ObjLable = item['ObjLable']
MAC_number = MAC_number + 1
MacPackId = 'MacPackID' + str(MAC_number)
IPPackID = item['IPPackID']
sentmac = item['Mac_data']
# 循环MACID来获取下一级rcptmac
for i in range(len(self.MACID)-1):
if sentmac == self.MACID[i]:
rcptmac = self.MACID[i+1]
sourceip = item['sourceip']
targetip = item['targetip']
sourceAppAddr = item['sourceAppAddr']
targetAppAddr = item['targetAppAddr']
MacPackedString = {
'ObjID': ObjID,
'ObjLable': ObjLable,
'MAC_number': MAC_number,
'MacPackId': MacPackId,
'IPPackID': IPPackID,
'sentmac': sentmac,
'rcptmac': rcptmac,
'sourceip': sourceip,
'targetip': targetip,
'sourceAppAddr': sourceAppAddr,
'targetAppAddr': targetAppAddr
}
MacPackedString_All.append(MacPackedString)
return MacPackedString_All
# 建立一个使应用层数据包进行拆分的函数
def Spilt_AppData(AppPackSize):
# 将获取的数据包大小进行拆分
page = int(AppPackSize) / 2048
# 定义一个初始值
page_true = 0
if page < 1 and page != 0:
page_true = int(page) + 1
elif page % 1 == 0:
page_true = int(page)
elif page % 1 > 0:
page_true = int(page) + 1
return page_true
# 建立一个进行TransData数据封包函数
def insert_TransData(num, AppPackedString):
TransPackID_Riget = num
ObjID = AppPackedString['ObjID']
ObjLable = AppPackedString['ObjLable']
TransPackID = 'TransPack'+str(TransPackID_Riget)
TransSeq = str(TransPackID_Riget)
TransTag = AppPackedString['ObjLable']+str(TransPackID_Riget)
AppPackId = AppPackedString['AppPackId']
sentport_one = AppPackedString['sourceAppAddr'].split(':')
# print(sentport_one)
sentport = sentport_one[1]
# print(sentport)
rpctport_one = AppPackedString['targetAppAddr'].split(':')
rpctport = rpctport_one[1]
sourceAppAddr = AppPackedString['sourceAppAddr']
targetAppAddr = AppPackedString['targetAppAddr']
timestamp = datetime.datetime.now().strftime('%H:%M:%S')
Mac_data = AppPackedString['Mac_data']
TransPackedString = {
'ObjID': ObjID,
'ObjLable': ObjLable,
'TransPackID': TransPackID,
'TransSeq': TransSeq,
'TransTag': TransTag,
'AppPackId': AppPackId,
'sentport': sentport,
'rpctport': rpctport,
'sourceAppAddr': sourceAppAddr,
'targetAppAddr': targetAppAddr,
'timestamp': timestamp,
'Mac_data': Mac_data
}
# print(TransPackedString)
return TransPackedString
if __name__ == '__main__':
# 建立一个列表来存放ObjID里的MAC地址 , test
MACID = ['00:1a:8c:10:ad:30', '00:1a:8c:10:ad:30']
# MACID = {
# 'A': 'MacA',
# 'R1': 'MacR1',
# 'R2': 'MacR2',
# 'R4': 'MacR4',
# 'R5': 'MacR5',
# 'D': 'MacD'
# }
# 定义一个数据用来模拟前台发送过来的数据:字典类型最好, test
# 这个位置需要的使一个字典列表, 至少需要两个以上的字典
'''
ShowData为字典数组进行到第三步需要将数据修改进行替换,
此数据需要前端传入后端以json格式
'''
# port 好需要通过random来实现
ShowData = [
{
'id': 1,
'ObjID': 'SHO1',
'ObjType':1,
'ObjLable': 'A',
'IPAddr': '196.168.1.1', # 起始IP地址
'ObjX': 210,
'ObjY': 130,
'MACAddr': '00:1a:8c:10:ad:30' # test用mac地址
},
{
'id': 1,
'ObjID': 'SRO1',
'ObjType': 2,
'ObjLable': 'R1',
'IPAddr': '196.168.3.1', # 最终IP地址
'ObjX': 210,
'ObjY':130,
'MACAddr': '00:1a:8c:10:ad:30'
}
]
AppPackTag_Data = {
'AppPackID': 'AppPack1',
'AppPackSize': 6144,
'AppPackTag': 'A-6144-Data'
}
# 需要定义一个最终IP地址路由节点用来进行测试 test
# 测试主程序
AllData = AllData(MACID, ShowData, AppPackTag_Data)
test = AllData.AppData()
print(test)
test_1 = AllData.TransData(test)
print(test_1)
test_2 = AllData.IPData(test_1)
print(test_2)
print(AllData.MACData(test_2))
'''
封包函数数据以全部可以获取现在进行主机和路由器之间的交互
'''

@ -1,170 +0,0 @@
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses.
Considerations for licensors: Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. More considerations for licensors.
Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensors permission is not necessary for any reasonfor example, because of any applicable exception or limitation to copyrightthen that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. More considerations for the public.
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License
By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
Section 1 Definitions.
a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
b. Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
c. BY-NC-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses, approved by Creative Commons as essentially the equivalent of this Public License.
d. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
e. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
f. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
g. License Elements means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution, NonCommercial, and ShareAlike.
h. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
i. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
j. Licensor means the individual(s) or entity(ies) granting rights under this Public License.
k. NonCommercial means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this Public License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange.
l. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
m. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
n. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
Section 2 Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
A. reproduce and Share the Licensed Material, in whole or in part, for NonCommercial purposes only; and
B. produce, reproduce, and Share Adapted Material for NonCommercial purposes only.
2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
3. Term. The term of this Public License is specified in Section 6(a).
4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
5. Downstream recipients.
A. Offer from the Licensor Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
B. Additional offer from the Licensor Adapted Material. Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapters License You apply.
C. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this Public License.
3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties, including when the Licensed Material is used other than for NonCommercial purposes.
Section 3 License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified form), You must:
A. retain the following if it is supplied by the Licensor with the Licensed Material:
i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of warranties;
v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
b. ShareAlike.In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply.
1. The Adapters License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-NC-SA Compatible License.
2. You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material.
3. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter's License You apply.
Section 4 Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database for NonCommercial purposes only;
b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material, including for purposes of Section 3(b); and
c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
Section 5 Disclaimer of Warranties and Limitation of Liability.
a. Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.
b. To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.
c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
Section 6 Term and Termination.
a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
Section 7 Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
Section 8 Interpretation.
a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
Creative Commons may be contacted at creativecommons.org.

@ -1,2 +1,195 @@
# NetWork # 项目编程基本原则
## 文档及代码编辑的注意事项
### 进度汇报
**查文档和编程任务是否符合。**
首先自查一遍文档,每个编程任务是否符合文档上编程任务的要求---请在进度表中标示【自查:符合 或 不符合】是按编程任务不是按X1,X2...
**查命名问题,函数框架,函数名称,和变量名规范**
(2)按我们前两天讨论的,主函数框架、函数关系调用图、函数名称与变量名称规范化等方面回复【已优化完成,未优化完成】
### 主函数框架示例:
```python
# 需要导入的库
from tkinter import scrolledtext # 下拉框
from tkinter import END # 下拉框自动下拉到最后一行
from pymouse import PyMouse # 模拟鼠标自动点击
import tkinter as tk # UI界面
import threading # 多线程任务
import win32gui # 获取扫雷窗口信息
import random # 随机数
import time # 应用sleep函数睡眠
"""按照上宽下窄的方式排列引用"""
"""
所有的系统库或第三方库,一次性引出,避免因为确少库而导致运行不了。
如果是自写的模块,可以在函数前引出
"""
#方式1--在文件中定义全局变量,加载全局变量定义文件(如果全局变量实在太多)
from setting import * # setting为自定义程序存放的是全局变量导入全局变量
# setting中定义了哪些全局变量及其定义
#方式2--直接定义全局常量和变量(一般多)
全局常量
GLOBAL ... ... # 常量用大写,大写字母下划线链接
全局变量
Init_Matrix ... ... # 全局变量首字母大写
"""按照上宽下窄的方式排列引用"""
注释标准:
就近对齐规则
print("数据集中图片的个数:", len(data_list)) # 打印图片数据集中图片的个数
print("第一个图片数组的形状:", data_list[0].shape) # 打印第一个图片数组的形状
print("第一个图片数组的内容:\n", data_list[0]) # 打印第一个图片数组的内容
return data_list # 返回加载成功的图像数据列表
###########
'此处说明是放函数定义的地方'
###########
# 主控函数, 将函数定义拷贝到main函数上面将函数调用放在main函数
if __name__ == '__main__':
pass
###########
'此处说明是函数调用的地方'
###########
"""
要求主函数框架单独运行不报错
"""
```
```python
# 文档贴函数提示说明 如下图所示
###########################################################################
# 以func1()[编程章节]==>func2()[编程章节]的方式说明调用当前函数要用的前述函数。
set_random_state()[5.1]==>create_boards()[5.4]==>show_window()[5.4]
```
![img_2.png](img_2.png)
### 根据不同情况不同的贴程序方法
```python
# 情况一
##### 第一次出现init初始化方法需要写全 #####
##### 在类里面增添方法,需要将类名写出,再写方法 #####
X2:
class MineSweeper: # 建立扫雷类
def __init__(self): # 第一次出现init初始化方法需要写全
def f2():
pass
# 情况二
##### 如果函数实在太多,需要标出函数调用关系图,同时将贴合编程要求的程序给出 #####
X3: # f1(), f2(), f3(), f4(), ..., f10() 本段仅给出f4(), 完整的在[位置](可以在文档末尾建立附录)。
Class Class_some
...
def f4(): 体现核心功能的函数给出。
pass
# 情况三
##### 如果需要在后续编程章节中扩充原有的功能,可以扩写函数,#####
##### 而且不要出现已经出现过的代码,已经出现过的代码用...代指 #####
X4: 【友好阅读性原则;最小重复代码原则;递增式代码表达原则;界面元素处理与业务逻辑完全分开原则】
class MineSweeper: # 扩展扫雷类--在X2基础上进一步定义
# _init_(self), f2(), 一并处理
def _init_(self): #在原函数基础上增加/调整
...
self.par = "example"
def f3():
...
def f4():
...
每个函数不超一页,原则上就是半页。
```
## 项目编程的普遍要求
### GUI界面和数据结构分开
借用前后端分离的架构模式。
GUI界面负责处理用户界面的展示和交互数据结构部分负责处理业务逻辑和数据处理。
将GUI界面负和数据结构分为两个独立的部分各自负责不同的功能和任务。GUI界面通过接口函数与更新和加载数据结构。
### 代码命名规则:
在Python中有一些命名规则和约定被广泛遵循以提高代码的可读性和一致性。
全局变量:首字母大写单词之间用下划线分隔。
变量和函数名使用小写字母单词之间使用下划线snake_case进行分隔。例如my_variable, calculate_result。
常量使用全大写字母单词之间使用下划线进行分隔。例如MAX_VALUE, PI。
类名使用驼峰命名法CamelCase即首字母大写不使用下划线。例如MyClass, Calculator。
模块名使用小写字母单词之间使用下划线进行分隔。例如my_module, utils。
- 首先是做好程序的优化,即做好程序函数的封装。 每个函数的函数名尽可能符合文档的编程任务及其要求--要让读者看到函数名就能想到编程任务,这样会更易于理解。
- 函数调用关系图的理解是正确的,就是要有一张全局关系图。
- 正确理解X1、X2、X3、X4和X5。通常X1仅是围绕数据结构赋值和界面或者界面元素坐标无关。X2是依据数据结构中的数据做输出通常是仅输出。X3通常可以定义函数或者定义类及其中的函数。X4是在X2基础上做界面交互元素同时将界面交互元素相关的事件/消息绑定X3或X5的函数。X5也是一些函数。这样界面逻辑和业务逻辑是完全分离的。
- 注意自前向后编程是越来越复杂但不要用后面的编程直接替代前面的编程任务中的程序前面是简单的后面是复杂的。例如“Select Sno from Student”,这是前面的编程Select :attr1 from :table1"尽管将attr1赋值成Sno将table1赋值成Student,也能实现前面的语句,但不可用后面的替换前面的。
### 函数调用关系图:
函数调用图Function Call Graph是用于描述程序中函数之间调用关系的图形表示。它展示了函数之间的依赖关系和调用流程帮助我们理解程序的执行流程和函数之间的交互
在函数调用图中,函数被表示为节点,函数之间的调用关系被表示为边。每个函数调用都会生成一个新的节点和一条连接调用者和被调用者的边。函数调用图可以是有向图或无向图,具体取决于函数调用的方向性。
调用图可以用软件生成。
![img.png](img.png)
### 项目文件应包含(后续规范)
项目应该包含以下基本文件:
1. README.md项目的说明文档包含项目的介绍、使用方法、安装指南、贡献指南等重要信息。README.md通常是其他开发者了解和使用项目的入口。
2. LICENSE项目的开源许可证明确了项目的使用条件和权利限制。选择适合项目的开源许可证对于保护项目的权益和推动开源合作非常重要。
3. .gitignoreGit版本控制系统的忽略文件配置用于指定哪些文件或目录应该被忽略不纳入版本控制。通常包括一些编译生成的文件、临时文件、敏感信息等。
4. requirements.txt项目的依赖项清单列出了项目所需的外部库、框架和工具的版本信息。这样其他开发者可以方便地安装相同的依赖项确保项目的可重复性和一致性。
5. setup.py 或者 setup.cfg用于打包和发布项目的配置文件。可以定义项目的元数据、依赖关系、安装过程等以便其他人能够方便地安装和使用项目。
6. docs 目录包含项目的文档例如用户手册、API文档、开发者指南等。良好的文档对于其他开发者和用户理解和使用项目非常重要。
7. tests 目录:包含项目的测试代码和测试数据,用于验证项目的正确性和稳定性。包括单元测试、集成测试等,帮助开发者确保项目的质量和可靠性。
8. src 或者 lib 目录:包含项目的源代码文件。根据项目的规模和结构,可以进一步组织成子目录或包,方便代码的组织和维护。
除了上述基本文件,根据项目的特点和需求,还可以包含其他文件,如配置文件、示例代码、演示视频等。重要的是根据项目的具体情况进行文件的组织和描述,确保项目的可理解性、可维护性和可扩展性。
```bash
# 将输出重定向到文件:
pip freeze > requirements.txt
# 老师一键安装项目所有依赖一般像Pycharm会自动识别这个文件按提示安装即可
pip install -r requirements.txt
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="34px" height="40px" viewBox="0 0 34 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>主机</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#0055D7" offset="0%"></stop>
<stop stop-color="#4BC1FF" offset="100%"></stop>
</linearGradient>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
<stop stop-color="#0042BE" offset="0%"></stop>
<stop stop-color="#0073FC" offset="100%"></stop>
</linearGradient>
<linearGradient x1="34.9365234%" y1="39.183214%" x2="50%" y2="70.6841363%" id="linearGradient-3">
<stop stop-color="#0054D5" offset="0%"></stop>
<stop stop-color="#2A92EE" offset="100%"></stop>
</linearGradient>
<linearGradient x1="78.125%" y1="66.0866477%" x2="21.875%" y2="27.2061435%" id="linearGradient-4">
<stop stop-color="#3DA5FF" offset="0%"></stop>
<stop stop-color="#7EFFFF" offset="100%"></stop>
</linearGradient>
<linearGradient x1="50%" y1="0%" x2="50%" y2="77.6337595%" id="linearGradient-5">
<stop stop-color="#0080E3" offset="0%"></stop>
<stop stop-color="#0072C4" offset="100%"></stop>
</linearGradient>
<linearGradient x1="88.7402344%" y1="46.21875%" x2="21.1230469%" y2="53.78125%" id="linearGradient-6">
<stop stop-color="#8FC4FE" offset="0%"></stop>
<stop stop-color="#1896F6" offset="100%"></stop>
</linearGradient>
<linearGradient x1="13.234747%" y1="63.3167614%" x2="100%" y2="63.3167614%" id="linearGradient-7">
<stop stop-color="#7E8CAA" offset="0%"></stop>
<stop stop-color="#C7CDD9" offset="100%"></stop>
</linearGradient>
<linearGradient x1="50.6091477%" y1="44.7228065%" x2="48.1508876%" y2="50%" id="linearGradient-8">
<stop stop-color="#6B7997" offset="0%"></stop>
<stop stop-color="#4B4E55" offset="100%"></stop>
</linearGradient>
</defs>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="4网络构建与联通V2.0" transform="translate(-268.000000, -696.000000)">
<g id="主机" transform="translate(268.000000, 696.000000)">
<polygon id="路径-81" fill="url(#linearGradient-1)" points="23.8461538 30 23.8461538 31.5384615 30.7692308 33.8461538 16.9230769 40 6.15384615 35.3846154 10 33.8461538 18.4615385 30 23.8461538 27.6923077"></polygon>
<polygon id="路径-82" fill="url(#linearGradient-2)" points="16.9230769 40 16.9230769 35.3846154 16.9230769 30 6.15384615 35.3846154"></polygon>
<polygon id="路径-88" fill="url(#linearGradient-3)" points="26.1538462 32.3076923 16.9230769 35.3846154 16.9230769 30 23.8461538 27.6923077 23.8461538 31.5384615"></polygon>
<polygon id="路径-77" fill="url(#linearGradient-4)" points="11.5384615 33.8461538 8.46153846 8.46153846 30.7692308 0 33.8461538 24.6153846"></polygon>
<polygon id="路径-78" fill="url(#linearGradient-5)" points="11.5384615 33.8461538 1.53846154 27.6923077 0 8.46153846 8.46153846 8.46153846"></polygon>
<polygon id="路径-79" fill="url(#linearGradient-6)" points="30.7692308 0 20.7692308 0.769230769 0 8.46153846 8.46153846 8.46153846"></polygon>
<polygon id="路径-80" fill="url(#linearGradient-7)" points="11.5384615 10 29.2307692 3.84615385 31.5384615 22.3076923 13.8461538 30"></polygon>
<polygon id="路径-83" fill="url(#linearGradient-8)" points="11.5384615 10 13.0769231 10 15.3846154 29.2307692 13.8461538 30"></polygon>
<line x1="29.2307692" y1="3.84615385" x2="31.5384615" y2="22.3076923" id="路径-85" stroke="#0056D7" stroke-width="0.769230769"></line>
<line x1="29.2307692" y1="3.84615385" x2="11.5384615" y2="10" id="路径-86" stroke="#2DA2E9" stroke-width="0.769230769"></line>
<line x1="31.5384615" y1="22.3076923" x2="13.8461538" y2="30" id="路径-86" stroke="#92D6FF" stroke-width="0.769230769"></line>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

@ -0,0 +1,391 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="54px" height="23px" viewBox="0 0 54 23" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>交换机</title>
<defs>
<linearGradient x1="13.6935089%" y1="47.3733367%" x2="98.4463875%" y2="51.0994595%" id="linearGradient-1">
<stop stop-color="#8FC4FE" offset="0%"></stop>
<stop stop-color="#1896F6" offset="100%"></stop>
</linearGradient>
<linearGradient x1="8.49955214%" y1="56.2692825%" x2="100%" y2="43.7307175%" id="linearGradient-2">
<stop stop-color="#3DA5FF" offset="0%"></stop>
<stop stop-color="#7EFFFF" offset="100%"></stop>
</linearGradient>
<linearGradient x1="50%" y1="0%" x2="50%" y2="77.6337595%" id="linearGradient-3">
<stop stop-color="#0080E3" offset="0%"></stop>
<stop stop-color="#0072C4" offset="100%"></stop>
</linearGradient>
<filter x="-86.1%" y="-83.3%" width="272.1%" height="266.7%" filterUnits="objectBoundingBox" id="filter-4">
<feGaussianBlur stdDeviation="0.327635328" in="SourceGraphic"></feGaussianBlur>
</filter>
<filter x="-86.1%" y="-83.3%" width="272.1%" height="266.7%" filterUnits="objectBoundingBox" id="filter-5">
<feGaussianBlur stdDeviation="0.327635328" in="SourceGraphic"></feGaussianBlur>
</filter>
<polygon id="path-6" points="0.640744615 0.660701538 1.65175385 0.660701538 1.65175385 2.07608615 0.640744615 2.07608615"></polygon>
<polygon id="path-8" points="0.615267692 0.670326154 1.65175385 0.670326154 1.65175385 2.08571077 0.615267692 2.08571077"></polygon>
<polygon id="path-10" points="0.577193846 0.680092308 1.65175385 0.680092308 1.65175385 2.09547692 0.577193846 2.09547692"></polygon>
<polygon id="path-12" points="0.532609231 0.691132308 1.65175385 0.691132308 1.65175385 2.10651692 0.532609231 2.10651692"></polygon>
<polygon id="path-14" points="0.472030769 0.701464615 1.65175385 0.701464615 1.65175385 2.11684923 0.472030769 2.11684923"></polygon>
<polygon id="path-16" points="0.410461538 0.00297230769 1.65175385 0.00297230769 1.65175385 1.41835692 0.410461538 1.41835692"></polygon>
<polygon id="path-18" points="0.0428861538 0.0795446154 1.45827077 0.0795446154 1.45827077 1.41538462 0.0428861538 1.41538462"></polygon>
<polygon id="path-20" points="0.619938462 0.0837907692 2.03532308 0.0837907692 2.03532308 1.41538462 0.619938462 1.41538462"></polygon>
<polygon id="path-22" points="0.478258462 0.0837907692 1.89364308 0.0837907692 1.89364308 1.41538462 0.478258462 1.41538462"></polygon>
<polygon id="path-24" points="0.402535385 0.0782707692 1.81792 0.0782707692 1.81792 1.41538462 0.402535385 1.41538462"></polygon>
<polygon id="path-26" points="0.351156923 0.0733169231 1.76654154 0.0733169231 1.76654154 1.41538462 0.351156923 1.41538462"></polygon>
<polygon id="path-28" points="0.29256 0.06992 1.70794462 0.06992 1.70794462 1.41538462 0.29256 1.41538462"></polygon>
<polygon id="path-30" points="0.246843077 0.0622769231 1.66222769 0.0622769231 1.66222769 1.41538462 0.246843077 1.41538462"></polygon>
<polygon id="path-32" points="0.201550769 0.0561907692 1.61693538 0.0561907692 1.61693538 1.41538462 0.201550769 1.41538462"></polygon>
<polygon id="path-34" points="0.156541538 0.0505292308 1.57192615 0.0505292308 1.57192615 1.41538462 0.156541538 1.41538462"></polygon>
<polygon id="path-36" points="0.110966154 0.0394892308 1.52635077 0.0394892308 1.52635077 1.41538462 0.110966154 1.41538462"></polygon>
<polygon id="path-38" points="0.0660984615 0.0326953846 1.48148308 0.0326953846 1.48148308 1.41538462 0.0660984615 1.41538462"></polygon>
<polygon id="path-40" points="0.0203815385 0.0209476923 1.43576615 0.0209476923 1.43576615 1.41538462 0.0203815385 1.41538462"></polygon>
<polygon id="path-42" points="0.683913846 0.0133046154 2.09929846 0.0133046154 2.09929846 1.41538462 0.683913846 1.41538462"></polygon>
</defs>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="4网络构建与联通V2.0" transform="translate(-93.000000, -705.000000)">
<g id="交换机" transform="translate(120.000000, 716.500000) scale(-1, 1) translate(-120.000000, -716.500000) translate(93.000000, 705.000000)">
<g id="编组-11">
<polygon id="路径-58" fill="url(#linearGradient-1)" points="13.4190069 12.2371795 53.3905169 8.84615385 35.3752544 0 0 2.35897436"></polygon>
<polygon id="路径-59" fill="url(#linearGradient-2)" points="53.3905169 8.84615385 53.3905169 18.8717949 13.4190069 23 13.4190069 12.2371795"></polygon>
<polygon id="路径-60" fill="url(#linearGradient-3)" points="0 2.35897436 13.4190069 12.2371795 13.4190069 23 0 12.6794872"></polygon>
<path d="M25.5947804,19.3515137 L25.0201833,19.3716737 L24.9201833,19.3786737 L24.9811833,19.3736737 L24.6525948,19.3860849 L24.6525948,19.170015 L24.8239013,19.1786578 L24.8239013,19.0317303 L25.1661833,19.0196737 L25.1665142,17.3463855 L23.4534495,17.4953992 L23.4531833,19.1276737 L23.7960625,19.1008727 L23.7960625,19.2478002 L23.9673689,19.2391574 L23.9673689,19.4552272 L23.0251833,19.507084 L23.0251833,17.1735296 L25.5947804,17.0006737 L25.5947804,19.3515137 Z" id="形状结合" fill="#FFFFFF" transform="translate(24.309982, 18.253879) rotate(-2.000000) translate(-24.309982, -18.253879) "></path>
<path d="M22.0258956,19.7938214 L21.4512985,19.8139814 L21.3512985,19.8209814 L21.4122985,19.8159814 L21.08371,19.8283926 L21.08371,19.6123227 L21.2550165,19.6209655 L21.2550165,19.474038 L21.5972985,19.4619814 L21.5976294,17.7886932 L19.8845647,17.9377069 L19.8842985,19.5699814 L20.2271776,19.5431804 L20.2271776,19.6901079 L20.3984841,19.6814651 L20.3984841,19.8975349 L19.4562985,19.9493917 L19.4562985,17.6158373 L22.0258956,17.4429814 L22.0258956,19.7938214 Z" id="形状结合" fill="#FFFFFF" transform="translate(20.741097, 18.696187) rotate(-2.000000) translate(-20.741097, -18.696187) "></path>
<g id="编组-8" transform="translate(33.355051, 16.388638) rotate(-2.000000) translate(-33.355051, -16.388638) translate(27.855051, 12.888638)">
<polygon id="矩形" stroke="#FFFFFF" stroke-width="0.5" points="0 0.810897436 10.4687288 0 10.4687288 5.67628205 0 6.48717949"></polygon>
<polygon id="矩形" fill="#FFFFFF" points="0 3.37873932 10.4687288 2.56784188 10.4687288 3.24358974 0 4.05448718"></polygon>
<line x1="2.6171822" y1="0.540598291" x2="2.6171822" y2="6.35202991" id="路径-61" stroke="#FFFFFF" stroke-width="0.5"></line>
<line x1="5.2343644" y1="0.405448718" x2="5.2343644" y2="6.21688034" id="路径-61" stroke="#FFFFFF" stroke-width="0.5"></line>
<line x1="7.98240571" y1="0.135149573" x2="7.98240571" y2="5.9465812" id="路径-61" stroke="#FFFFFF" stroke-width="0.5"></line>
</g>
<g id="编组-8" transform="translate(45.701249, 15.072345) rotate(-2.000000) translate(-45.701249, -15.072345) translate(40.201249, 11.572345)">
<polygon id="矩形" stroke="#FFFFFF" stroke-width="0.5" points="0 0.810897436 10.4687288 0 10.4687288 5.67628205 0 6.48717949"></polygon>
<polygon id="矩形" fill="#FFFFFF" points="0 3.37873932 10.4687288 2.56784188 10.4687288 3.24358974 0 4.05448718"></polygon>
<line x1="2.6171822" y1="0.540598291" x2="2.6171822" y2="6.35202991" id="路径-61" stroke="#FFFFFF" stroke-width="0.5"></line>
<line x1="5.2343644" y1="0.405448718" x2="5.2343644" y2="6.21688034" id="路径-61" stroke="#FFFFFF" stroke-width="0.5"></line>
<line x1="7.98240571" y1="0.135149573" x2="7.98240571" y2="5.9465812" id="路径-61" stroke="#FFFFFF" stroke-width="0.5"></line>
</g>
<g id="编组-9" transform="translate(16.131359, 14.006410)" fill="#18D6FF">
<ellipse id="椭圆形" filter="url(#filter-4)" cx="0.571021571" cy="0.58974359" rx="1" ry="1"></ellipse>
<ellipse id="椭圆形" cx="0.571021571" cy="0.58974359" rx="1" ry="1"></ellipse>
</g>
<g id="编组-9" transform="translate(16.131359, 16.365385)" fill="#18D6FF">
<ellipse id="椭圆形" filter="url(#filter-5)" cx="0.571021571" cy="0.58974359" rx="1" ry="1"></ellipse>
<ellipse id="椭圆形" cx="0.571021571" cy="0.58974359" rx="1" ry="1"></ellipse>
</g>
<g id="编组-10" transform="translate(1.998575, 5.750000)" fill="#0A609F" stroke="#0865A7" stroke-width="0.5">
<line x1="0" y1="0" x2="9.42185592" y2="6.78205128" id="路径-62"></line>
<line x1="0" y1="1.62179487" x2="9.42185592" y2="8.40384615" id="路径-62"></line>
<line x1="0" y1="3.39102564" x2="9.42185592" y2="10.1730769" id="路径-62"></line>
<line x1="0" y1="5.16025641" x2="9.42185592" y2="11.9423077" id="路径-62"></line>
<line x1="0" y1="6.92948718" x2="9.42185592" y2="13.7115385" id="路径-62"></line>
</g>
<polygon id="矩形" stroke="#0865A7" stroke-width="0.5" fill="#0A609F" points="12.2769638 15.1858974 12.8479853 15.9230769 12.8479853 18.4294872 12.2769638 17.6923077"></polygon>
<polygon id="矩形" stroke="#0865A7" stroke-width="0.5" fill="#0A609F" points="0.428266178 6.78205128 0.999287749 7.51923077 0.999287749 10.025641 0.428266178 9.28846154"></polygon>
</g>
<g id="编组" transform="translate(17.692308, 2.653846)">
<g transform="translate(14.153846, 2.225423)">
<mask id="mask-7" fill="white">
<use xlink:href="#path-6"></use>
</mask>
<g id="Clip-45"></g>
<polygon id="Fill-44" fill="#0F819B" mask="url(#mask-7)" points="1.15806769 1.99116308 1.51332923 0.755532308 1.53880615 0.745624615 1.19486769 1.98267077"></polygon>
</g>
<g transform="translate(14.153846, 2.225423)">
<mask id="mask-9" fill="white">
<use xlink:href="#path-8"></use>
</mask>
<g id="Clip-49"></g>
<polygon id="Fill-48" fill="#0F859F" mask="url(#mask-9)" points="1.13188308 2.00078769 1.47440615 0.765156923 1.51403692 0.755249231 1.15877538 1.99088"></polygon>
</g>
<g transform="translate(14.153846, 2.225423)">
<mask id="mask-11" fill="white">
<use xlink:href="#path-10"></use>
</mask>
<g id="Clip-57"></g>
<polygon id="Fill-56" fill="#1089A3" mask="url(#mask-11)" points="1.09451692 2.01055385 1.43704 0.773507692 1.47525538 0.765015385 1.13131692 2.00064615"></polygon>
</g>
<g transform="translate(14.153846, 2.225423)">
<mask id="mask-13" fill="white">
<use xlink:href="#path-12"></use>
</mask>
<g id="Clip-81"></g>
<path d="M1.38891692,0.781716923 C1.39457846,0.780301538 1.39882462,0.780301538 1.40448615,0.778886154 L1.43704,0.773224615 L1.09451692,2.01027077 L1.07045538,2.01876308 C1.06337846,2.02159385 1.05347077,2.02300923 1.04356308,2.02442462 L1.38891692,0.781716923 Z" id="Fill-80" fill="#108CA7" mask="url(#mask-13)"></path>
</g>
<g transform="translate(14.153846, 2.225423)">
<mask id="mask-15" fill="white">
<use xlink:href="#path-14"></use>
</mask>
<g id="Clip-83"></g>
<path d="M1.3156,0.791341538 C1.32126154,0.791341538 1.32692308,0.789926154 1.334,0.788510769 C1.34249231,0.788510769 1.34956923,0.787095385 1.35664615,0.78568 C1.36796923,0.784264615 1.37929231,0.782849231 1.3892,0.781433846 L1.04384615,2.02414154 C1.02544615,2.02838769 1.00563077,2.03121846 0.985815385,2.03546462 L0.970246154,2.03688 L1.3156,0.791341538 Z" id="Fill-82" fill="#108FAB" mask="url(#mask-15)"></path>
</g>
<g transform="translate(14.153846, 2.933116)">
<mask id="mask-17" fill="white">
<use xlink:href="#path-16"></use>
</mask>
<g id="Clip-85"></g>
<path d="M1.3156,0.0836492308 L0.970246154,1.32918769 L0.920707692,1.33768 L1.26747692,0.0893107692 C1.28446154,0.0878953846 1.29861538,0.0850646154 1.3156,0.0836492308" id="Fill-84" fill="#1093AF" mask="url(#mask-17)"></path>
</g>
<polygon id="Fill-96" fill="#0B6173" points="12.4348615 4.50546646 11.9338154 3.95346646 12.2805846 2.70651262 12.7802154 3.25709723"></polygon>
<polygon id="Fill-98" fill="#1198B6" points="15.4211815 3.02228492 15.0758277 4.27065415 12.43472 4.505608 12.7800738 3.25723877"></polygon>
<polygon id="Fill-100" fill="#1093AF" points="12.7085969 3.26290031 12.7807815 3.25723877 12.4354277 4.505608 12.3773969 4.50136185"></polygon>
<polygon id="Fill-102" fill="#108EA9" points="12.7085969 3.26290031 12.2075508 2.71231569 12.2811508 2.70523877 12.7807815 3.25723877"></polygon>
<polygon id="Fill-104" fill="#0A5D6F" points="12.3768308 4.50136185 11.8757846 3.94936185 12.2084 2.71231569 12.7080308 3.26290031"></polygon>
<polygon id="Fill-106" fill="#1192AD" points="12.6214092 3.26148492 12.1203631 2.71090031 12.2081169 2.71231569 12.7091631 3.26290031"></polygon>
<path d="M12.5364862,3.26148492 L12.03544,2.70948492 C12.0651631,2.70948492 12.0934708,2.71090031 12.1217785,2.71090031 L12.6214092,3.26148492 L12.5364862,3.26148492" id="Fill-108" fill="#1088A2"></path>
<polygon id="Fill-109" fill="#1197B3" points="12.5364862 3.26148492 12.6214092 3.26148492 12.7091631 3.26290031 12.3765477 4.50136185 12.1840554 4.50843877 12.1741477 4.50843877 12.5195015 3.26006954"></polygon>
<polygon id="Fill-111" fill="#0B5F72" points="12.1742892 4.50815569 11.6732431 3.95615569 12.0200123 2.70920185 12.5196431 3.25978646"></polygon>
<polygon id="Fill-113" fill="#1192AD" points="12.5199262 3.26006954 12.0202954 2.70948492 12.0358646 2.70948492 12.5369108 3.26148492"></polygon>
<polygon id="Fill-115" fill="#1093AF" points="12.0817231 4.50136185 12.4242462 3.26573108 12.5204923 3.26006954 12.1737231 4.50843877 12.1581538 4.50843877"></polygon>
<polygon id="Fill-117" fill="#0A5D6F" points="12.0817231 4.50136185 11.5806769 3.95077723 11.9246154 2.71373108 12.4242462 3.26573108"></polygon>
<polygon id="Fill-119" fill="#108EA9" points="12.4245292 3.26558954 11.9248985 2.71358954 12.0197292 2.70934338 12.51936 3.259928"></polygon>
<polygon id="Fill-121" fill="#0A5B6C" points="12.0235508 4.49711569 11.5225046 3.94511569 11.8664431 2.70948492 12.3660738 3.26006954"></polygon>
<polygon id="Fill-123" fill="#108FAB" points="12.0235508 4.49711569 12.3660738 3.26006954 12.4241046 3.26573108 12.0815815 4.50136185"></polygon>
<polygon id="Fill-125" fill="#108AA5" points="12.3664985 3.26006954 11.8668677 2.70948492 11.9248985 2.71373108 12.4245292 3.26573108"></polygon>
<polygon id="Fill-127" fill="#0F839D" points="12.3207815 3.24761415 11.8197354 2.69561415 11.8664431 2.709768 12.3660738 3.26035262"></polygon>
<polygon id="Fill-129" fill="#0A596A" points="11.9772677 4.49301108 11.4762215 3.94101108 11.8102523 2.69405723 12.3112985 3.24605723"></polygon>
<path d="M12.2648738,3.24067877 L11.7652431,2.69009415 C11.7808123,2.69150954 11.7949662,2.69292492 11.80912,2.69434031 L12.3101662,3.24634031 C12.2945969,3.24492492 12.2804431,3.24350954 12.2648738,3.24067877" id="Fill-131" fill="#0E7C93"></path>
<path d="M12.3111569,3.24619877 L11.8101108,2.69419877 C11.8143569,2.69419877 11.8171877,2.69561415 11.8200185,2.69561415 L12.3210646,3.24761415 C12.3168185,3.24619877 12.3139877,3.24619877 12.3111569,3.24619877" id="Fill-132" fill="#0E7F97"></path>
<path d="M12.3207815,3.24761415 L12.3660738,3.26035262 L12.0235508,4.49739877 L11.9909969,4.494568 C11.9867508,4.494568 11.9810892,4.49315262 11.9768431,4.49315262 L12.3108738,3.24619877 C12.31512,3.24619877 12.3179508,3.24619877 12.3207815,3.24761415" id="Fill-133" fill="#108CA7"></path>
<path d="M12.2648738,3.24067877 C12.2804431,3.24350954 12.2945969,3.24492492 12.3101662,3.24634031 L11.9775508,4.49329415 C11.97472,4.49329415 11.9718892,4.49329415 11.9704738,4.49187877 C11.9534892,4.49046338 11.9365046,4.489048 11.91952,4.48621723 L12.2648738,3.24067877 Z" id="Fill-135" fill="#1089A3"></path>
<polygon id="Fill-137" fill="#0A5767" points="11.9199446 4.48607569 11.4203138 3.93407569 11.7656677 2.68995262 12.2652985 3.24053723"></polygon>
<path d="M12.2545415,3.23940492 L11.7534954,2.68882031 C11.7577415,2.68882031 11.7619877,2.68882031 11.7648185,2.69023569 L12.2644492,3.24082031 C12.2616185,3.24082031 12.2573723,3.24082031 12.2545415,3.23940492" id="Fill-139" fill="#0D7990"></path>
<path d="M12.2191569,3.23657415 L12.2545415,3.23940492 C12.2573723,3.24082031 12.2616185,3.24082031 12.2644492,3.24082031 L11.9205108,4.48635877 C11.9049415,4.483528 11.8893723,4.48211262 11.8738031,4.47928185 L12.2191569,3.23657415 Z" id="Fill-140" fill="#0F859F"></path>
<polygon id="Fill-142" fill="#0E8199" points="12.2191569 3.23657415 11.7181108 2.68598954 11.7534954 2.68882031 12.2545415 3.23940492"></polygon>
<polygon id="Fill-144" fill="#095565" points="11.8743692 4.47914031 11.3747385 3.92855569 11.7186769 2.685848 12.2197231 3.23643262"></polygon>
<polygon id="Fill-146" fill="#0E7D95" points="12.1728738 3.23374338 11.6718277 2.68174338 11.7185354 2.68598954 12.2195815 3.23657415"></polygon>
<polygon id="Fill-148" fill="#095262" points="11.82936 4.46951569 11.3283138 3.91893108 11.6722523 2.68188492 12.1732985 3.23388492"></polygon>
<path d="M11.82936,4.46951569 L12.1732985,3.23388492 L12.2185908,3.23671569 L11.8746523,4.47942338 C11.8619138,4.478008 11.8534215,4.47659262 11.8435138,4.47517723 L11.82936,4.46951569 Z" id="Fill-150" fill="#0F819B"></path>
<polygon id="Fill-152" fill="#0D758C" points="12.1515015 3.22694954 11.6518708 2.67494954 11.6731015 2.68202646 12.1727323 3.23402646"></polygon>
<polygon id="Fill-154" fill="#094E5D" points="11.7389169 4.45564492 11.2378708 3.90506031 11.5832246 2.663768 12.0828554 3.215768"></polygon>
<polygon id="Fill-156" fill="#0C6C80" points="12.0374215 3.20755877 11.5363754 2.65555877 11.5406215 2.65555877 12.0402523 3.20755877"></polygon>
<polygon id="Fill-157" fill="#084C5A" points="11.6939077 4.44602031 11.1928615 3.89402031 11.5368 2.65555877 12.0378462 3.20755877"></polygon>
<polygon id="Fill-159" fill="#084957" points="11.638 4.43087569 11.1383692 3.88029108 11.4808923 2.64466031 11.9805231 3.19666031"></polygon>
<path d="M11.9697662,3.193688 L11.46872,2.641688 C11.4729662,2.64310338 11.4772123,2.64451877 11.4814585,2.64451877 L11.9810892,3.19651877 C11.9768431,3.19510338 11.9725969,3.19510338 11.9697662,3.193688" id="Fill-161" fill="#0B6579"></path>
<polygon id="Fill-162" fill="#084755" points="11.6262523 4.43087569 11.1266215 3.87887569 11.4691446 2.64182954 11.9701908 3.19382954"></polygon>
<polygon id="Fill-164" fill="#0D738A" points="9.04558154 2.02571262 9.54521231 2.57629723 11.9697662 3.19340492 11.46872 2.64423569"></polygon>
<path d="M11.9808062,3.19651877 L11.4811754,2.64451877 C11.4995754,2.64876492 11.5179754,2.65159569 11.5377908,2.65584185 L12.0374215,3.20784185 C12.0176062,3.20359569 11.9992062,3.19934954 11.9808062,3.19651877" id="Fill-166" fill="#0C687C"></path>
<path d="M12.04096,3.20755877 L11.5399138,2.65555877 L11.5823754,2.66405108 L12.0820062,3.21605108 C12.0678523,3.21322031 12.0551138,3.21038954 12.04096,3.20755877" id="Fill-167" fill="#0C6C80"></path>
<path d="M12.0824308,3.21590954 L11.5828,2.66390954 C11.5969538,2.66674031 11.6125231,2.66815569 11.6280923,2.67098646 L12.1277231,3.22298646 C12.1121538,3.22015569 12.098,3.21732492 12.0824308,3.21590954" id="Fill-168" fill="#0D6F84"></path>
<path d="M12.1280062,3.22270338 L11.62696,2.67070338 C11.6354523,2.67211877 11.6439446,2.67353415 11.6524369,2.67494954 L12.1520677,3.22694954 C12.1435754,3.22553415 12.1350831,3.22411877 12.1280062,3.22270338" id="Fill-169" fill="#0D7288"></path>
<path d="M12.1280062,3.22270338 L11.62696,2.67070338 L12.1280062,3.22270338 Z M12.0827138,3.21562646 L11.7472677,4.42436492 L11.7840677,4.46399569 L12.1280062,3.22270338 C12.1124369,3.21987262 12.0982831,3.21704185 12.0827138,3.21562646 L12.0827138,3.21562646 Z" id="Fill-170" fill="#09505F"></path>
<path d="M12.1280062,3.22270338 C12.1350831,3.22411877 12.1435754,3.22553415 12.1520677,3.22694954 L12.1732985,3.23402646 L11.82936,4.46965723 L11.8038831,4.46824185 L11.7840677,4.46399569 L12.1280062,3.22270338 Z" id="Fill-172" fill="#0E7E97"></path>
<path d="M11.7389169,4.45564492 L12.0828554,3.215768 C12.0970092,3.21718338 12.1125785,3.22001415 12.1281477,3.22284492 L11.7842092,4.46413723 C11.7757169,4.46272185 11.7672246,4.46130646 11.7587323,4.45989108 C11.7516554,4.45847569 11.7445785,4.45706031 11.7389169,4.45564492" id="Fill-174" fill="#0E7B92"></path>
<path d="M12.0374215,3.20755877 L12.0402523,3.20755877 C12.0544062,3.21038954 12.0671446,3.21322031 12.0812985,3.21605108 L11.7387754,4.455928 C11.7217908,4.45309723 11.7076369,4.44885108 11.6934831,4.44602031 L12.0374215,3.20755877 Z" id="Fill-176" fill="#0D778E"></path>
<path d="M11.638,4.43087569 L11.9805231,3.19666031 C11.9989231,3.19949108 12.0187385,3.20373723 12.0371385,3.20798338 L11.6946154,4.44644492 C11.6847077,4.44361415 11.6748,4.44219877 11.6663077,4.439368 L11.638,4.43087569 Z" id="Fill-178" fill="#0D7389"></path>
<path d="M11.9808062,3.19651877 L11.6382831,4.43073415 L11.62696,4.43073415 L11.9694831,3.193688 C11.9737292,3.19510338 11.9779754,3.19510338 11.9808062,3.19651877" id="Fill-180" fill="#0C7085"></path>
<polygon id="Fill-184" fill="#084755" points="9.25576615 4.72244492 8.75472 4.17044492 9.09865846 2.93198338 9.59970462 3.48398338"></polygon>
<polygon id="Fill-186" fill="#084C5A" points="9.22745846 4.74325108 8.72641231 4.19125108 9.07176615 2.94995877 9.57139692 3.50054338"></polygon>
<polygon id="Fill-188" fill="#094E5D" points="9.21429538 4.75004492 8.71324923 4.19804492 9.05860308 2.95533723 9.55823385 3.50733723"></polygon>
<polygon id="Fill-190" fill="#09505F" points="9.18726154 4.76108492 8.68763077 4.20908492 9.03156923 2.96637723 9.53261538 3.51837723"></polygon>
<polygon id="Fill-192" fill="#095262" points="9.16178462 4.77085108 8.66215385 4.21885108 9.00609231 2.97614338 9.50713846 3.526728"></polygon>
<polygon id="Fill-194" fill="#095565" points="9.12371077 4.78189108 8.62408 4.22989108 8.96801846 2.985768 9.46906462 3.537768"></polygon>
<polygon id="Fill-196" fill="#0A5767" points="9.08648615 4.79024185 8.58544 4.23824185 8.93079385 2.99411877 9.43184 3.54611877"></polygon>
<polygon id="Fill-198" fill="#0A596A" points="9.03666462 4.79986646 8.53703385 4.24786646 8.88238769 3.002328 9.38201846 3.554328"></polygon>
<polygon id="Fill-200" fill="#1088A2" points="9.30756923 3.57102954 8.80652308 3.01902954 8.86455385 3.00629108 9.3656 3.55687569"></polygon>
<polygon id="Fill-202" fill="#0A5B6C" points="9.23425231 3.83372492 8.73462154 3.28172492 8.80680615 3.01987877 9.30785231 3.57046338"></polygon>
<polygon id="Fill-204" fill="#108EA9" points="9.27020308 3.56834031 8.77057231 3.01634031 8.80737231 3.01917108 9.30700308 3.57117108"></polygon>
<g transform="translate(7.784615, 2.225423)">
<path d="M1.48629538,1.34008615 L0.985249231,0.789501538 C1.01638769,0.786670769 1.04469538,0.78384 1.07158769,0.781009231 L1.57263385,1.33159385 C1.54574154,1.33584 1.51601846,1.33867077 1.48629538,1.34008615" id="Fill-206" fill="#0D6E84"></path>
<path d="M1.57206769,1.33187692 L1.07102154,0.781292308 C1.07385231,0.781292308 1.07668308,0.779876923 1.07951385,0.779876923 L1.58056,1.33187692 L1.57206769,1.33187692" id="Fill-207" fill="#0C6B80"></path>
</g>
<g transform="translate(7.784615, 2.225423)">
<polygon id="Fill-208" fill="#0F829B" points="1.58027692 1.33187692 1.07923077 0.779876923 1.08064615 0.779876923"></polygon>
<path d="M1.58098462,1.33187692 L1.07993846,0.779876923 C1.0856,0.778461538 1.09126154,0.778461538 1.09692308,0.777046154 L1.59796923,1.32904615 C1.59230769,1.33046154 1.58664615,1.33046154 1.58098462,1.33187692" id="Fill-209" fill="#0E7E96"></path>
</g>
<path d="M9.38216,3.55446954 L8.88111385,3.00246954 C8.89951385,3.00105415 8.91508308,2.99822338 8.93065231,2.99397723 L9.43169846,3.54597723 C9.41471385,3.548808 9.39914462,3.55163877 9.38216,3.55446954" id="Fill-210" fill="#0E7B93"></path>
<path d="M9.43127385,3.54626031 L8.93022769,2.99426031 C8.94438154,2.99284492 8.95712,2.98859877 8.96844308,2.985768 L9.46807385,3.537768 C9.45675077,3.54059877 9.44401231,3.54342954 9.43127385,3.54626031" id="Fill-211" fill="#0E788F"></path>
<g transform="translate(8.492308, 2.225423)">
<path d="M0.976332308,1.31248615 L0.475286154,0.760486154 C0.485193846,0.759070769 0.495101538,0.75624 0.503593846,0.753409231 L1.00464,1.30540923 C0.994732308,1.30824 0.98624,1.30965538 0.976332308,1.31248615" id="Fill-212" fill="#0D758C"></path>
<path d="M1.00393231,1.30555077 L0.502886154,0.753550769 C0.507132308,0.752135385 0.509963077,0.75072 0.514209231,0.75072 L1.01384,1.30130462 L1.00393231,1.30555077" id="Fill-213" fill="#0D7288"></path>
</g>
<path d="M9.50657231,3.52686954 L9.00552615,2.97628492 C9.01543385,2.97345415 9.02392615,2.97062338 9.03241846,2.96637723 L9.53204923,3.51837723 C9.52355692,3.521208 9.51506462,3.52403877 9.50657231,3.52686954" id="Fill-214" fill="#0D6F84"></path>
<g transform="translate(8.492308, 2.225423)">
<path d="M1.03988308,1.29309538 L0.538836923,0.741095385 C0.544498462,0.73968 0.548744615,0.738264615 0.552990769,0.736849231 L1.05262154,1.28743385 C1.04837538,1.28884923 1.04412923,1.29168 1.03988308,1.29309538" id="Fill-215" fill="#0C6C81"></path>
<path d="M1.05304615,1.28757538 L0.552,0.736990769 C0.557661538,0.73416 0.561907692,0.732744615 0.566153846,0.729913846 L1.06578462,1.28191385 C1.06153846,1.28332923 1.05729231,1.28616 1.05304615,1.28757538" id="Fill-216" fill="#0C697D"></path>
</g>
<g transform="translate(8.492308, 2.225423)">
<path d="M1.06620923,1.28205538 L0.565163077,0.730055385 C0.570824615,0.72864 0.575070769,0.725809231 0.579316923,0.724393846 L1.07894769,1.27497846 C1.07470154,1.27780923 1.07045538,1.27922462 1.06620923,1.28205538" id="Fill-217" fill="#0C667A"></path>
<polygon id="Fill-218" fill="#0B6376" points="1.07852308 1.27512 0.578892308 0.724535385 0.578892308 0.724535385"></polygon>
</g>
<g transform="translate(8.492308, 2.225423)">
<path d="M1.09310154,1.26691077 L0.592055385,0.716326154 C0.593470769,0.714910769 0.594886154,0.714910769 0.594886154,0.714910769 L1.09593231,1.26549538 C1.09451692,1.26691077 1.09310154,1.26691077 1.09310154,1.26691077" id="Fill-219" fill="#0B5D6F"></path>
<path d="M1.09579077,1.26549538 L0.594744615,0.714910769 C0.598990769,0.71208 0.603236923,0.709249231 0.606067692,0.706418462 L1.10711385,1.25841846 C1.10286769,1.26124923 1.09862154,1.26266462 1.09579077,1.26549538" id="Fill-220" fill="#0A5A6C"></path>
</g>
<polygon id="Fill-221" fill="#084957" points="9.08507077 2.94217415 9.08082462 2.96057415 9.57196308 3.50125108 9.23227077 4.72414338 9.24076308 4.73405108 9.58611692 3.49275877"></polygon>
<path d="M9.57153846,3.50054338 L9.07190769,2.94995877 C9.07615385,2.947128 9.0804,2.94429723 9.08464615,2.94146646 L9.58569231,3.49205108 C9.58003077,3.49488185 9.57578462,3.49771262 9.57153846,3.50054338" id="Fill-223" fill="#0B6072"></path>
<g transform="translate(8.492308, 2.225423)">
<polygon id="Fill-224" fill="#0A5868" points="1.10697231 1.25856 0.605926154 0.70656 0.607341538 0.70656"></polygon>
<path d="M1.10697231,1.25856 L0.607341538,0.70656 L0.617249231,0.698067692 L1.11688,1.25006769 C1.11404923,1.25289846 1.11121846,1.25572923 1.10697231,1.25856" id="Fill-225" fill="#095565"></path>
<polygon id="Fill-226" fill="#095262" points="1.11730462 1.25020923 0.617673846 0.698209231 0.62192 0.693963077 1.12155077 1.24596308"></polygon>
</g>
<path d="M9.62956923,3.45355262 L9.12852308,2.90155262 C9.13135385,2.89872185 9.13276923,2.89589108 9.1356,2.89306031 L9.63523077,3.44364492 C9.63381538,3.44647569 9.63098462,3.45072185 9.62956923,3.45355262" id="Fill-227" fill="#095060"></path>
<path d="M9.12923077,2.90211877 L9.12215385,2.93042646 L9.61329231,3.47110338 C9.60904615,3.47534954 9.6048,3.47959569 9.59913846,3.48384185 L9.48873846,3.88156492 L9.50572308,3.90138031 L9.63027692,3.45411877 L9.12923077,2.90211877 Z" id="Fill-228" fill="#094D5C"></path>
<g transform="translate(8.492308, 2.225423)">
<path d="M1.12140923,1.24610462 L0.621778462,0.694104615 C0.621778462,0.692689231 0.623193846,0.692689231 0.624609231,0.691273846 L1.12424,1.24327385 C1.12282462,1.24327385 1.12282462,1.24468923 1.12140923,1.24610462" id="Fill-230" fill="#09505F"></path>
<path d="M1.12494769,1.24341538 L0.623901538,0.691415385 C0.626732308,0.688584615 0.628147692,0.687169231 0.630978462,0.684338462 L1.13060923,1.23633846 C1.12919385,1.23775385 1.12636308,1.24058462 1.12494769,1.24341538" id="Fill-231" fill="#094D5C"></path>
<path d="M1.13103385,1.23648 L0.629987692,0.68448 C0.632818462,0.681649231 0.634233846,0.678818462 0.637064615,0.677403077 L1.13669538,1.22798769 C1.13386462,1.23081846 1.13244923,1.23364923 1.13103385,1.23648" id="Fill-232" fill="#084A58"></path>
</g>
<path d="M9.59928,3.48398338 L9.26524923,4.69130646 L9.27374154,4.69979877 L9.61343385,3.47124492 C9.60918769,3.47549108 9.60494154,3.47973723 9.59928,3.48398338" id="Fill-233" fill="#084552"></path>
<polygon id="Fill-235" fill="#0A5B6C" points="8.96405538 4.80680185 8.46300923 4.25621723 8.73476308 3.28243262 9.23439385 3.83443262"></polygon>
<path d="M9.59928,3.48398338 C9.60494154,3.47973723 9.60918769,3.47549108 9.61343385,3.47124492 L9.27374154,4.69979877 L9.25534154,4.72244492 L9.59928,3.48398338 Z" id="Fill-237" fill="#0C7085"></path>
<path d="M9.62900308,3.45355262 L9.62475692,3.47195262 L9.29072615,4.67644492 C9.28931077,4.68210646 9.28506462,4.687768 9.28223385,4.69201415 L9.27374154,4.70050646 L9.61343385,3.47195262 C9.62051077,3.46629108 9.62475692,3.46062954 9.62900308,3.45355262" id="Fill-239" fill="#0C6D81"></path>
<path d="M9.59928,3.48398338 L9.25534154,4.72244492 L9.24118769,4.733768 L9.58512615,3.49247569 C9.59078769,3.48964492 9.59503385,3.48681415 9.59928,3.48398338" id="Fill-241" fill="#0D7389"></path>
<path d="M9.57153846,3.50054338 C9.57578462,3.49771262 9.58003077,3.49488185 9.58569231,3.49205108 L9.24175385,4.73334338 L9.23326154,4.73900492 C9.23043077,4.74042031 9.22901538,4.74183569 9.2276,4.74325108 L9.57153846,3.50054338 Z" id="Fill-243" fill="#0D778E"></path>
<path d="M9.57153846,3.50054338 L9.2276,4.74325108 C9.22618462,4.74325108 9.22476923,4.74466646 9.22335385,4.74466646 L9.21769231,4.74891262 C9.21627692,4.74891262 9.21486154,4.750328 9.21486154,4.750328 L9.5588,3.50762031 C9.56304615,3.50478954 9.56729231,3.50337415 9.57153846,3.50054338" id="Fill-245" fill="#0E7B92"></path>
<path d="M9.21429538,4.75004492 C9.20580308,4.75429108 9.19731077,4.75712185 9.18740308,4.761368 L9.53275692,3.51866031 C9.54124923,3.51441415 9.54974154,3.51158338 9.55823385,3.50733723 L9.21429538,4.75004492 Z" id="Fill-247" fill="#0E7E97"></path>
<path d="M9.16178462,4.77085108 L9.50713846,3.526728 C9.51563077,3.52389723 9.52412308,3.52106646 9.53261538,3.51823569 L9.18726154,4.76094338 C9.18584615,4.76235877 9.18443077,4.76235877 9.18301538,4.76377415 L9.17027692,4.76802031 C9.16744615,4.76943569 9.16461538,4.76943569 9.16178462,4.77085108" id="Fill-249" fill="#0F819B"></path>
<g transform="translate(8.492308, 2.225423)">
<path d="M1.13726154,1.22812923 L0.636215385,0.676129231 C0.639046154,0.673298462 0.640461538,0.670467692 0.643292308,0.667636923 L1.14292308,1.21822154 C1.14150769,1.22105231 1.13867692,1.22529846 1.13726154,1.22812923" id="Fill-251" fill="#095060"></path>
<path d="M1.14278154,1.21850462 L0.643150769,0.666504615 C0.650227692,0.652350769 0.654473846,0.635366154 0.651643077,0.616966154 L1.15268923,1.16896615 C1.15410462,1.18736615 1.15127385,1.20293538 1.14278154,1.21850462" id="Fill-252" fill="#094D5D"></path>
</g>
<path d="M9.12371077,4.78189108 L9.46906462,3.537768 C9.48180308,3.53493723 9.49454154,3.53069108 9.50728,3.52644492 L9.16192615,4.770568 C9.15201846,4.77339877 9.14069538,4.77764492 9.12795692,4.78047569 C9.12654154,4.78047569 9.12512615,4.78189108 9.12371077,4.78189108" id="Fill-253" fill="#0F859F"></path>
<path d="M9.08648615,4.79024185 L9.43184,3.54611877 C9.44457846,3.543288 9.45731692,3.54045723 9.46864,3.53762646 L9.12328615,4.78174954 C9.11196308,4.78458031 9.09922462,4.78741108 9.08648615,4.79024185" id="Fill-255" fill="#1089A3"></path>
<path d="M9.03666462,4.79986646 L9.38201846,3.554328 C9.39900308,3.55149723 9.41598769,3.54866646 9.43155692,3.54583569 L9.08620308,4.78995877 C9.08195692,4.79137415 9.07912615,4.79137415 9.07488,4.79278954 C9.06638769,4.79420492 9.05789538,4.79562031 9.04798769,4.79845108 C9.04515692,4.79845108 9.04091077,4.79845108 9.03666462,4.79986646" id="Fill-257" fill="#108CA7"></path>
<path d="M9.30756923,3.57102954 L9.3656,3.55687569 C9.36984615,3.55546031 9.37550769,3.55546031 9.38258462,3.55404492 L9.03723077,4.79958338 C9.03156923,4.79958338 9.02732308,4.80099877 9.02166154,4.80241415 L8.96363077,4.80666031 L9.23396923,3.83429108 L9.30756923,3.57102954 Z" id="Fill-259" fill="#108FAB"></path>
<polygon id="Fill-261" fill="#094B59" points="9.27020308 3.56834031 8.77057231 3.01634031 8.77057231 3.01492492 9.27020308 3.56550954"></polygon>
<path d="M9.27020308,3.56834031 L9.27020308,3.56550954 C9.30417231,3.56409415 9.33531077,3.56126338 9.36503385,3.55701723 L9.30700308,3.57117108 L9.27020308,3.56834031 Z" id="Fill-263" fill="#094B59"></path>
<polygon id="Fill-267" fill="#108EA9" points="9.26128615 3.56692492 8.76024 3.01492492 8.77014769 3.01634031 9.26977846 3.56834031"></polygon>
<polygon id="Fill-269" fill="#1093AF" points="9.23425231 3.83372492 8.96391385 4.80609415 8.91437538 4.81458646 9.26114462 3.56763262 9.26963692 3.569048 9.30785231 3.57046338"></polygon>
<path d="M11.9537723,0.745780308 L11.9537723,0.750026462 L11.9523569,0.750026462 L11.9537723,0.747195692 C11.9537723,0.747195692 11.9537723,0.747195692 11.9537723,0.745780308" id="Fill-300" fill="#08434F"></path>
<path d="M11.92136,0.783146462 L11.5788369,2.01877723 L11.5519446,2.03010031 L11.8944677,0.795884923 C11.8987138,0.793054154 11.9015446,0.791638769 11.9043754,0.788808 L11.92136,0.783146462 Z" id="Fill-302" fill="#0D778E"></path>
<path d="M11.9621231,0.733324923 L11.9692,0.727663385 L11.6266769,1.96329415 L11.6096923,1.98594031 L11.9536308,0.750309538 L11.9536308,0.746063385 C11.9550462,0.744648 11.9564615,0.743232615 11.9564615,0.741817231 C11.9592923,0.738986462 11.9607077,0.736155692 11.9621231,0.733324923" id="Fill-313" fill="#0B697D"></path>
<path d="M11.8888062,0.798291077 C11.8902215,0.796875692 11.8930523,0.795460308 11.8944677,0.795460308 L11.5519446,2.02967569 L11.5377908,2.03958338 L11.8817292,0.803952615 L11.8888062,0.798291077 Z" id="Fill-319" fill="#0E7B92"></path>
<polygon id="Fill-323" fill="#0E7E97" points="11.8549785 0.813577231 11.8818708 0.803669538 11.5379323 2.03930031 11.5124554 2.05062338"></polygon>
<polygon id="Fill-327" fill="#0F819B" points="11.4859877 2.060248 11.8299262 0.823201846 11.8554031 0.813294154 11.51288 2.05034031"></polygon>
<path d="M11.7914277,0.832968 C11.7985046,0.831552615 11.8069969,0.828721846 11.8140738,0.827306462 L11.8296431,0.823060308 L11.4857046,2.06010646 L11.4489046,2.06859877 L11.7914277,0.832968 Z" id="Fill-333" fill="#0F859F"></path>
<path d="M11.7914277,0.832968 L11.2903815,0.282383385 L11.7914277,0.832968 Z M11.7546277,0.842875692 L11.4220123,2.04029108 L11.4489046,2.06859877 L11.7914277,0.832968 C11.7801046,0.837214154 11.7673662,0.840044923 11.7546277,0.842875692 L11.7546277,0.842875692 Z" id="Fill-356" fill="#095565"></path>
<path d="M11.4092738,2.08515877 L11.7546277,0.842451077 C11.7673662,0.839620308 11.7801046,0.836789538 11.7914277,0.832543385 L11.4489046,2.06817415 L11.4262585,2.08091262 C11.4205969,2.082328 11.4149354,2.08374338 11.4092738,2.08515877" id="Fill-358" fill="#1089A3"></path>
<path d="M11.3594523,2.09492492 L11.7048062,0.850801846 C11.7217908,0.847971077 11.7387754,0.845140308 11.7543446,0.842309538 L11.4089908,2.08501723 C11.3934215,2.087848 11.3764369,2.09209415 11.3594523,2.09492492" id="Fill-360" fill="#108CA7"></path>
<path d="M11.6310646,0.860568 C11.6423877,0.860568 11.6522954,0.857737231 11.6622031,0.856321846 C11.6664492,0.856321846 11.6706954,0.856321846 11.6749415,0.854906462 C11.6848492,0.853491077 11.6947569,0.852075692 11.7046646,0.850660308 L11.3593108,2.09478338 C11.3508185,2.09619877 11.3437415,2.09902954 11.3366646,2.09902954 L11.2871262,2.10469108 L11.6310646,0.860568 Z" id="Fill-365" fill="#108FAB"></path>
<path d="M11.6310646,0.860568 L11.2871262,2.10469108 L11.2489108,2.11318338 L11.59568,0.864814154 C11.6070031,0.863398769 11.6197415,0.861983385 11.6310646,0.860568" id="Fill-367" fill="#1093AF"></path>
<path d="M5.19899077,3.15773723 L5.70003692,3.70973723 C5.68446769,3.70407569 5.67031385,3.69982954 5.65474462,3.694168 L5.31788308,4.908568 L5.35468308,4.94961415 L5.70003692,3.70973723 L5.19899077,3.15773723 Z" id="Fill-481" fill="#07424F"></path>
<path d="M1.60660308,2.81634646 L1.95054154,1.57222338 C1.96328,1.57505415 1.97601846,1.57930031 1.98875692,1.58213108 C1.99017231,1.58213108 1.99300308,1.58354646 1.99583385,1.58354646 L1.65048,2.82908492 C1.64481846,2.82766954 1.63915692,2.82625415 1.63349538,2.82342338 L1.61651077,2.81917723 L1.60660308,2.81634646 Z" id="Fill-561" fill="#0C7085"></path>
<path d="M1.31843077,0.983564923 L1.81947692,1.53414954 C1.81523077,1.53414954 1.8124,1.53273415 1.80956923,1.53131877 L1.57178462,1.26805723 L1.80956923,1.53131877 C1.79824615,1.52707262 1.78692308,1.52282646 1.7756,1.51858031 L1.43873846,2.72873415 L1.47553846,2.77119569 L1.81947692,1.53414954 L1.31843077,0.983564923 Z" id="Fill-585" fill="#07404D"></path>
<path d="M15.68232,2.71967569 C15.7955508,2.78619877 15.8281046,2.85130646 15.7898892,2.90367569 C15.6596738,2.98293723 15.6129662,2.99426031 15.5577662,3.004168 C15.5195508,3.01124492 15.4940738,3.01407569 15.4700123,3.01690646 C15.4530277,3.01832185 15.4374585,3.02115262 15.4204738,3.022568 L12.7807815,3.25752185 C12.6604738,3.26601415 12.5260123,3.26459877 12.3858892,3.25327569 C12.2471815,3.24195262 12.1042277,3.22213723 11.9697662,3.19382954 L9.54521231,2.57530646 L9.64428923,3.39481415 C9.64712,3.41604492 9.64145846,3.43586031 9.63013538,3.45426031 C9.49425846,3.53069108 9.48152,3.53493723 9.46878154,3.537768 C9.45745846,3.54059877 9.44472,3.54342954 9.43056615,3.54626031 C9.41499692,3.54909108 9.39942769,3.55192185 9.38244308,3.55475262 C9.33573538,3.56182954 9.30459692,3.56466031 9.27062769,3.56607569 L6.62102769,3.80244492 C6.58988923,3.80669108 6.55875077,3.80952185 6.52619692,3.81093723 C6.41296615,3.813768 6.31955077,3.81235262 6.22613538,3.80669108 C5.94730462,3.78404492 5.66705846,3.71752185 5.50570462,3.63259877 C5.42078154,3.58306031 5.38398154,3.53493723 5.38539692,3.49247569 C5.38822769,3.41321415 5.52410462,3.34952185 5.76613538,3.33112185 L6.84465846,3.23062954 L7.62170462,3.15986031 L8.01093538,3.12447569 L7.89770462,2.16201415 L5.03721231,1.45149108 L2.78392,1.64398338 C2.72447385,1.64964492 2.66219692,1.65247569 2.59708923,1.65106031 C2.57585846,1.65106031 2.55604308,1.65106031 2.53339692,1.64964492 C2.47819692,1.64822954 2.43856615,1.64681415 2.39752,1.642568 C2.11727385,1.62275262 1.83419692,1.56047569 1.67850462,1.47555262 C1.58367385,1.42035262 1.54545846,1.36515262 1.55819692,1.31702954 C1.57659692,1.24484492 1.70681231,1.18681415 1.93185846,1.16133723 L4.58428923,0.926383385 C4.69468923,0.919306462 4.82207385,0.920721846 4.95087385,0.929214154 C5.09807385,0.940537231 5.24952,0.966014154 5.37973538,0.999983385 L7.51413538,1.52933723 L7.82976615,1.60859877 L7.71936615,0.790506462 C7.72078154,0.702752615 7.85524308,0.631983385 8.09161231,0.616414154 L10.7313046,0.381460308 C10.8544431,0.371552615 10.9889046,0.372968 11.1219508,0.382875692 C11.4078585,0.404106462 11.68952,0.469214154 11.8452123,0.562629538 C11.9556123,0.626321846 11.9895815,0.688598769 11.9570277,0.742383385 C11.8678585,0.807491077 11.8437969,0.817398769 11.8140738,0.827306462 C11.7801046,0.837214154 11.7673662,0.840044923 11.7546277,0.842875692 C11.7376431,0.845706462 11.7220738,0.848537231 11.7036738,0.851368 C11.6810277,0.855614154 11.6569662,0.858444923 11.6314892,0.861275692 C11.6187508,0.862691077 11.6074277,0.862691077 11.5946892,0.864106462 L9.35413538,1.05942954 L9.47727385,2.02330646 L10.1962892,2.20447569 L12.3363508,2.746568 L14.5698277,2.53850646 C14.6915508,2.52859877 14.8260123,2.53001415 14.9576431,2.53992185 C15.24072,2.562568 15.5195508,2.62767569 15.68232,2.71967569" id="Fill-587" fill="#18D6FF"></path>
<path d="M9.54535385,2.57587262 L11.9699077,3.19439569 L11.6259692,4.43144185 L9.50572308,3.902088 L9.63027692,3.45341108 C9.6416,3.43501108 9.64726154,3.41661108 9.64443077,3.39396492 L9.54535385,2.57587262 Z" id="Fill-589" fill="#0E7A92"></path>
<polygon id="Fill-591" fill="#1198B6" points="9.26128615 3.56692492 8.91451692 4.81529415 6.27482462 5.050248 6.62017846 3.80187877"></polygon>
<g transform="translate(5.661538, 3.640808)">
<mask id="mask-19" fill="white">
<use xlink:href="#path-18"></use>
</mask>
<g id="Clip-594"></g>
<path d="M0.887163077,0.168006154 C0.911224615,0.166590769 0.935286154,0.16376 0.959347692,0.160929231 L0.613993846,1.40929846 C0.589932308,1.41212923 0.565870769,1.41354462 0.541809231,1.41354462 L0.887163077,0.168006154 Z" id="Fill-593" fill="#1093AF" mask="url(#mask-19)"></path>
</g>
<g transform="translate(4.953846, 3.640808)">
<mask id="mask-21" fill="white">
<use xlink:href="#path-20"></use>
</mask>
<g id="Clip-596"></g>
<path d="M1.57956923,0.169421538 C1.58381538,0.168006154 1.58947692,0.168006154 1.59513846,0.168006154 L1.24978462,1.41354462 C1.23421538,1.41496 1.22006154,1.41496 1.20590769,1.41496 L1.06012308,1.41354462 L1.40264615,0.176498462 L1.51446154,0.172252308 C1.53003077,0.170836923 1.54418462,0.170836923 1.55833846,0.169421538 L1.57249231,0.169421538 L1.57956923,0.169421538 Z" id="Fill-595" fill="#1197B3" mask="url(#mask-21)"></path>
</g>
<polygon id="Fill-597" fill="#1198B6" points="11.5951138 0.864672615 11.2483446 2.11304185 10.1967138 2.20362646 9.47769846 2.02245723 9.35456 1.05999569"></polygon>
<g transform="translate(4.953846, 3.640808)">
<mask id="mask-23" fill="white">
<use xlink:href="#path-22"></use>
</mask>
<g id="Clip-600"></g>
<polygon id="Fill-599" fill="#1093AF" mask="url(#mask-23)" points="0.967981538 1.40646769 1.31050462 0.169421538 1.40392 0.176498462 1.05998154 1.41354462"></polygon>
</g>
<polygon id="Fill-601" fill="#0D7991" points="6.84522462 3.23105415 6.34417846 2.68046954 7.12122462 2.60970031 7.62227077 3.15886954"></polygon>
<g transform="translate(4.953846, 3.640808)">
<mask id="mask-25" fill="white">
<use xlink:href="#path-24"></use>
</mask>
<g id="Clip-604"></g>
<polygon id="Fill-603" fill="#108FAB" mask="url(#mask-25)" points="0.909950769 1.40094769 1.25247385 0.165316923 1.31050462 0.169563077 0.967981538 1.40660923"></polygon>
</g>
<g transform="translate(4.953846, 3.640808)">
<mask id="mask-27" fill="white">
<use xlink:href="#path-26"></use>
</mask>
<g id="Clip-606"></g>
<polygon id="Fill-605" fill="#108CA7" mask="url(#mask-27)" points="1.19543385 0.161070769 1.25346462 0.165316923 0.909526154 1.40094769 0.864233846 1.39811692"></polygon>
</g>
<g transform="translate(4.953846, 3.640808)">
<mask id="mask-29" fill="white">
<use xlink:href="#path-28"></use>
</mask>
<g id="Clip-608"></g>
<polygon id="Fill-607" fill="#1089A3" mask="url(#mask-29)" points="0.805636923 1.39401231 1.14957538 0.156966154 1.19486769 0.161212308 0.863667692 1.39825846"></polygon>
</g>
<polygon id="Fill-609" fill="#0A5869" points="7.89841231 2.16258031 8.01022769 3.12504185 7.62241231 3.15901108"></polygon>
<g transform="translate(4.953846, 3.640808)">
<mask id="mask-31" fill="white">
<use xlink:href="#path-30"></use>
</mask>
<g id="Clip-614"></g>
<path d="M0.75992,1.38849231 L1.10385846,0.145784615 C1.11235077,0.1472 1.11942769,0.148615385 1.12792,0.150030769 L1.14915077,0.157107692 L0.805212308,1.39415385 L0.789643077,1.39273846 L0.75992,1.38849231 Z" id="Fill-613" fill="#0F859F" mask="url(#mask-31)"></path>
</g>
<g transform="translate(4.953846, 3.640808)">
<mask id="mask-33" fill="white">
<use xlink:href="#path-32"></use>
</mask>
<g id="Clip-616"></g>
<path d="M1.05856615,0.138990769 C1.07413538,0.141821538 1.08828923,0.144652308 1.10385846,0.146067692 L0.75992,1.38877538 C0.744350769,1.38594462 0.730196923,1.38452923 0.714627692,1.38169846 L1.05856615,0.138990769 Z" id="Fill-615" fill="#0F819B" mask="url(#mask-33)"></path>
</g>
<g transform="translate(4.953846, 3.640808)">
<mask id="mask-35" fill="white">
<use xlink:href="#path-34"></use>
</mask>
<g id="Clip-618"></g>
<path d="M1.04328,0.13616 C1.04752615,0.137575385 1.05318769,0.138990769 1.05884923,0.138990769 L0.714910769,1.38169846 C0.705003077,1.38028308 0.695095385,1.37886769 0.685187692,1.37603692 L0.669618462,1.37037538 L1.01355692,0.134744615 L1.04328,0.13616 Z" id="Fill-617" fill="#0E7E97" mask="url(#mask-35)"></path>
</g>
<g transform="translate(4.953846, 3.640808)">
<mask id="mask-37" fill="white">
<use xlink:href="#path-36"></use>
</mask>
<g id="Clip-620"></g>
<path d="M0.967981538,0.123704615 L0.970812308,0.123704615 C0.979304615,0.12512 0.987796923,0.126535385 0.996289231,0.129366154 L1.01327385,0.135027692 L0.669335385,1.37065846 L0.639612308,1.36924308 C0.635366154,1.36782769 0.63112,1.36782769 0.628289231,1.36641231 C0.626873846,1.36641231 0.625458462,1.36641231 0.624043077,1.36499692 L0.967981538,0.123704615 Z" id="Fill-619" fill="#0E7B92" mask="url(#mask-37)"></path>
</g>
<g transform="translate(4.953846, 3.640808)">
<mask id="mask-39" fill="white">
<use xlink:href="#path-38"></use>
</mask>
<g id="Clip-622"></g>
<path d="M0.922406154,0.115495385 L0.935144615,0.116910769 C0.942221538,0.118326154 0.950713846,0.119741538 0.957790769,0.121156923 C0.962036923,0.122572308 0.964867692,0.122572308 0.967698462,0.123987692 L0.62376,1.36528 C0.620929231,1.36528 0.618098462,1.36528 0.615267692,1.36386462 C0.613852308,1.36386462 0.612436923,1.36386462 0.611021538,1.36244923 L0.579883077,1.35254154 L0.922406154,0.115495385 Z" id="Fill-621" fill="#0D778E" mask="url(#mask-39)"></path>
</g>
<g transform="translate(4.953846, 3.640808)">
<mask id="mask-41" fill="white">
<use xlink:href="#path-40"></use>
</mask>
<g id="Clip-624"></g>
<path d="M0.878104615,0.104455385 C0.890843077,0.107286154 0.902166154,0.110116923 0.912073846,0.111532308 L0.921981538,0.115778462 L0.579458462,1.35282462 L0.549735385,1.34999385 C0.546904615,1.34857846 0.544073846,1.34857846 0.539827692,1.34716308 C0.538412308,1.34716308 0.535581538,1.34716308 0.534166154,1.34574769 L0.878104615,0.104455385 Z" id="Fill-623" fill="#0D7389" mask="url(#mask-41)"></path>
</g>
<g transform="translate(4.246154, 3.640808)">
<mask id="mask-43" fill="white">
<use xlink:href="#path-42"></use>
</mask>
<g id="Clip-626"></g>
<path d="M1.54092923,0.0961046154 L1.56216,0.0989353846 C1.56782154,0.100350769 1.57348308,0.100350769 1.57914462,0.101766154 C1.58056,0.103181538 1.58339077,0.103181538 1.58622154,0.104596923 L1.24228308,1.34588923 C1.23945231,1.34588923 1.23520615,1.34447385 1.23237538,1.34447385 L1.21680615,1.34022769 L1.19699077,1.33315077 L1.54092923,0.0961046154 Z" id="Fill-625" fill="#0C7085" mask="url(#mask-43)"></path>
</g>
<polygon id="Fill-627" fill="#0C6D81" points="5.40011692 4.95881415 5.74264 3.721768 5.78651692 3.73733723 5.44399385 4.97438338"></polygon>
<path d="M5.35510769,4.94918954 L5.69904615,3.70931262 C5.71178462,3.71355877 5.72593846,3.71638954 5.73867692,3.72063569 L5.74292308,3.72205108 L5.4004,4.95909723 L5.37633846,4.95768185 C5.36926154,4.95485108 5.36218462,4.95202031 5.35510769,4.94918954" id="Fill-629" fill="#0B697D"></path>
<path d="M5.65502769,3.69402646 C5.66918154,3.699688 5.68475077,3.70393415 5.69890462,3.70959569 L5.35496615,4.94947262 C5.34081231,4.94522646 5.32524308,4.94098031 5.31108923,4.93531877 L5.65502769,3.69402646 Z" id="Fill-631" fill="#0B6579"></path>
<path d="M5.60464,3.67605108 C5.62020923,3.683128 5.63719385,3.68878954 5.65559385,3.69445108 L5.31165538,4.93574338 C5.29891692,4.93149723 5.28759385,4.92725108 5.27627077,4.92158954 L5.25787077,4.91168185 L5.60180923,3.67463569 L5.60464,3.67605108 Z" id="Fill-633" fill="#0B6275"></path>
<path d="M5.20451077,4.88974338 L5.54703385,3.65269723 C5.56260308,3.65977415 5.58100308,3.66685108 5.59798769,3.673928 L5.60081846,3.67534338 L5.25829538,4.91238954 L5.23706462,4.90531262 C5.23564923,4.90531262 5.23423385,4.90531262 5.23281846,4.90389723 C5.22291077,4.89965108 5.21300308,4.89540492 5.20451077,4.88974338" id="Fill-635" fill="#0B5F71"></path>
<path d="M5.54731692,3.65255569 L5.20479385,4.88960185 C5.19064,4.88252492 5.17507077,4.875448 5.16233231,4.86837108 L5.04485538,4.71692492 L5.38454769,3.49261723 C5.38313231,3.53507877 5.42134769,3.58320185 5.50485538,3.63132492 C5.51759385,3.63840185 5.53316308,3.64547877 5.54731692,3.65255569" id="Fill-639" fill="#0A5B6D"></path>
<path d="M7.51413538,1.52947877 L7.72078154,0.786401846 C7.72078154,0.787817231 7.71936615,0.789232615 7.71936615,0.790648 L7.51413538,1.52947877 Z" id="Fill-645" fill="#063843"></path>
<polygon id="Fill-705" fill="#0E7A92" points="5.03650462 1.45078338 7.89841231 2.16272185 7.62241231 3.15915262 6.84536615 3.23133723 4.69256615 2.68641415"></polygon>
<polygon id="Fill-713" fill="#1198B6" points="5.03650462 1.45078338 4.69256615 2.68641415 2.43785846 2.89306031 2.78321231 1.64469108"></polygon>
<path d="M2.72277538,1.65120185 L2.78363692,1.64412492 L2.43686769,2.89249415 C2.41846769,2.89390954 2.39865231,2.89532492 2.37742154,2.89674031 L2.72277538,1.65120185 Z" id="Fill-715" fill="#1093AF"></path>
<path d="M2.59694769,1.65120185 L2.61110154,1.65120185 L2.66064,1.65120185 L2.72291692,1.65120185 L2.37756308,2.89674031 C2.35491692,2.89815569 2.33085538,2.89815569 2.30679385,2.89957108 L2.18790154,2.89674031 L2.53467077,1.64978646 C2.55165538,1.65120185 2.56722462,1.65120185 2.58420923,1.65120185 L2.59694769,1.65120185 Z" id="Fill-717" fill="#1197B3"></path>
<polygon id="Fill-719" fill="#1093AF" points="2.51811077 1.64978646 2.53368 1.64978646 2.18832615 2.89674031 2.09632615 2.88966338 2.43884923 1.65403262"></polygon>
<polygon id="Fill-721" fill="#108FAB" points="2.03787077 2.88555877 2.38180923 1.64851262 2.43984 1.65417415 2.09590154 2.88980492"></polygon>
<polygon id="Fill-723" fill="#108CA7" points="2.32321231 1.64426646 2.38124308 1.64851262 2.03730462 2.88555877 1.97927385 2.88131262"></polygon>
<path d="M1.93341538,2.877208 L2.27876923,1.63166954 L2.28301538,1.63166954 C2.28584615,1.63166954 2.28726154,1.63308492 2.29009231,1.63308492 L2.32264615,1.644408 L1.98012308,2.88145415 L1.93341538,2.877208 Z" id="Fill-725" fill="#1089A3"></path>
<path d="M2.23347692,1.62629108 C2.24904615,1.62770646 2.2632,1.62912185 2.27876923,1.63195262 L1.93341538,2.87749108 L1.90369231,2.87466031 C1.89661538,2.87466031 1.89236923,2.87324492 1.88812308,2.87324492 L2.23347692,1.62629108 Z" id="Fill-729" fill="#0F859F"></path>
<path d="M2.23135385,1.62487569 L1.88741538,2.87324492 C1.886,2.87324492 1.88458462,2.87182954 1.88175385,2.87182954 L1.84353846,2.85767569 L2.17473846,1.62062954 L2.23135385,1.62487569 Z" id="Fill-731" fill="#0F819B"></path>
<polygon id="Fill-733" fill="#0E7E97" points="1.78621538 2.85371262 2.12873846 1.61808185 2.17544615 1.62091262 1.84424615 2.85795877"></polygon>
<path d="M1.74064,2.84819262 L2.08599385,1.60265415 L2.12845538,1.61822338 L1.78593231,2.85385415 L1.76045538,2.85243877 C1.75620923,2.85102338 1.75196308,2.85102338 1.74771692,2.849608 C1.74488615,2.849608 1.74205538,2.84819262 1.74064,2.84819262" id="Fill-735" fill="#0E7B92"></path>
<polygon id="Fill-737" fill="#0D778E" points="1.69648 2.83432185 2.03900308 1.59869108 2.08571077 1.60293723 1.74035692 2.84847569 1.72195692 2.84422954"></polygon>
<path d="M1.99569231,1.58340492 L2.03956923,1.59897415 L1.69704615,2.83460492 L1.67156923,2.83318954 C1.66449231,2.83177415 1.65741538,2.83035877 1.65033846,2.82894338 L1.99569231,1.58340492 Z" id="Fill-739" fill="#0D7389"></path>
<path d="M1.92449846,1.56542954 C1.93299077,1.56826031 1.94148308,1.57109108 1.95139077,1.57250646 L1.60603692,2.81662954 L1.56357538,2.80106031 L1.90609846,1.56401415 L1.92449846,1.56542954 Z" id="Fill-741" fill="#0C6D81"></path>
<polygon id="Fill-743" fill="#0B697D" points="1.51955692 2.78591569 1.86208 1.54886954 1.90595692 1.56443877 1.56343385 2.80148492"></polygon>
<path d="M1.81876923,1.53372492 C1.82018462,1.53514031 1.8216,1.53514031 1.82301538,1.53655569 C1.83009231,1.53797108 1.83716923,1.54080185 1.84283077,1.54221723 L1.86264615,1.54929415 L1.52012308,2.78634031 L1.47624615,2.77077108 L1.81876923,1.53372492 Z" id="Fill-745" fill="#0B6579"></path>
<path d="M1.43236923,2.75562646 L1.77489231,1.51858031 C1.78621538,1.52282646 1.79753846,1.52707262 1.81027692,1.53131877 C1.81310769,1.53273415 1.81593846,1.53414954 1.81876923,1.53414954 L1.47624615,2.77119569 L1.43236923,2.75562646 Z" id="Fill-747" fill="#0B6275"></path>
<path d="M1.72124923,1.49635877 C1.73823385,1.50343569 1.75663385,1.511928 1.77503385,1.51900492 L1.43251077,2.75605108 L1.40420308,2.74755877 C1.39995692,2.744728 1.39571077,2.74331262 1.39146462,2.74048185 C1.38721846,2.73906646 1.38155692,2.73623569 1.37872615,2.73482031 L1.72124923,1.49635877 Z" id="Fill-749" fill="#0B5F71"></path>
<path d="M1.72124923,1.49635877 L1.37872615,2.73482031 C1.36315692,2.726328 1.34900308,2.71925108 1.33626462,2.71075877 L1.20746462,2.55931262 L1.55423385,1.31094338 L1.55848,1.31660492 C1.54574154,1.364728 1.58395692,1.419928 1.67878769,1.475128 C1.69152615,1.48220492 1.70709538,1.48928185 1.72124923,1.49635877" id="Fill-755" fill="#0A5B6D"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="33px" height="35px" viewBox="0 0 33 35" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>路由器</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#0042BE" offset="0%"></stop>
<stop stop-color="#0073FC" offset="100%"></stop>
</linearGradient>
<rect id="path-2" x="0" y="13.8738739" width="32.4774775" height="21.1261261" rx="2.52252252"></rect>
<linearGradient x1="100%" y1="56.8067642%" x2="0%" y2="40.3552058%" id="linearGradient-3">
<stop stop-color="#3DA5FF" offset="0%"></stop>
<stop stop-color="#7EFFFF" offset="100%"></stop>
</linearGradient>
<rect id="path-4" x="0" y="11.036036" width="32.4774775" height="21.1261261" rx="2.52252252"></rect>
<linearGradient x1="54.9387755%" y1="66.0866477%" x2="45.0612245%" y2="27.2061435%" id="linearGradient-5">
<stop stop-color="#3DA5FF" offset="0%"></stop>
<stop stop-color="#7EFFFF" offset="100%"></stop>
</linearGradient>
<linearGradient x1="-162.350446%" y1="50%" x2="100%" y2="50%" id="linearGradient-6">
<stop stop-color="#FFFFFF" offset="0%"></stop>
<stop stop-color="#FFFFFF" stop-opacity="0" offset="100%"></stop>
</linearGradient>
<linearGradient x1="48.3262804%" y1="34.4238281%" x2="50%" y2="79.7851562%" id="linearGradient-7">
<stop stop-color="#0054D5" offset="0%"></stop>
<stop stop-color="#2A92EE" offset="100%"></stop>
</linearGradient>
<linearGradient x1="0%" y1="50%" x2="266.454381%" y2="50%" id="linearGradient-8">
<stop stop-color="#0054D5" offset="0%"></stop>
<stop stop-color="#2A92EE" offset="100%"></stop>
</linearGradient>
</defs>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="4网络构建与联通V2.0" transform="translate(-22.000000, -699.000000)">
<g id="路由器" transform="translate(22.000000, 699.000000)">
<g id="矩形">
<use fill="#454343" xlink:href="#path-2"></use>
<use fill="url(#linearGradient-1)" xlink:href="#path-2"></use>
</g>
<g id="矩形">
<use fill="#5D5959" xlink:href="#path-4"></use>
<use fill="url(#linearGradient-3)" xlink:href="#path-4"></use>
</g>
<path d="M6.77927928,0 C7.7370704,-1.75943374e-16 8.51351351,0.776443114 8.51351351,1.73423423 L8.51351351,11.036036 L8.51351351,11.036036 L5.04504505,11.036036 L5.04504505,1.73423423 C5.04504505,0.776443114 5.82148816,1.75943374e-16 6.77927928,0 Z" id="矩形" fill="url(#linearGradient-5)"></path>
<path d="M6.14864865,1.26126126 C6.58400825,1.26126126 6.93693694,1.61418995 6.93693694,2.04954955 L6.93693694,11.036036 L6.93693694,11.036036 L5.36036036,11.036036 L5.36036036,2.04954955 C5.36036036,1.61418995 5.71328905,1.26126126 6.14864865,1.26126126 Z" id="矩形" fill="url(#linearGradient-6)"></path>
<path d="M26.3288288,0 C27.2866199,-1.75943374e-16 28.0630631,0.776443114 28.0630631,1.73423423 L28.0630631,11.036036 L28.0630631,11.036036 L24.5945946,11.036036 L24.5945946,1.73423423 C24.5945946,0.776443114 25.3710377,1.75943374e-16 26.3288288,0 Z" id="矩形" fill="url(#linearGradient-5)"></path>
<path d="M25.6981982,1.26126126 C26.1335578,1.26126126 26.4864865,1.61418995 26.4864865,2.04954955 L26.4864865,11.036036 L26.4864865,11.036036 L24.9099099,11.036036 L24.9099099,2.04954955 C24.9099099,1.61418995 25.2628386,1.26126126 25.6981982,1.26126126 Z" id="矩形" fill="url(#linearGradient-6)"></path>
<g id="编组-7" transform="translate(6.306306, 12.927928)">
<rect id="矩形" fill="url(#linearGradient-7)" x="0" y="0" width="1.26126126" height="3.78378378" rx="0.630630631"></rect>
<rect id="矩形" fill="url(#linearGradient-7)" x="2.52252252" y="0" width="1.26126126" height="3.78378378" rx="0.630630631"></rect>
<rect id="矩形" fill="url(#linearGradient-7)" x="5.36036036" y="0" width="1.26126126" height="3.78378378" rx="0.630630631"></rect>
<rect id="矩形" fill="url(#linearGradient-7)" x="7.88288288" y="0" width="1.26126126" height="3.78378378" rx="0.630630631"></rect>
<rect id="矩形" fill="url(#linearGradient-7)" x="10.7207207" y="0" width="1.26126126" height="3.78378378" rx="0.630630631"></rect>
<rect id="矩形" fill="url(#linearGradient-7)" x="13.2432432" y="0" width="1.26126126" height="3.78378378" rx="0.630630631"></rect>
<rect id="矩形" fill="url(#linearGradient-7)" x="16.0810811" y="0" width="1.26126126" height="3.78378378" rx="0.630630631"></rect>
<rect id="矩形" fill="url(#linearGradient-8)" x="18.6036036" y="0" width="1.26126126" height="3.78378378" rx="0.630630631"></rect>
</g>
<ellipse id="椭圆形" fill="#18D6FF" cx="8.1981982" cy="33.1081081" rx="1.26126126" ry="1"></ellipse>
<ellipse id="椭圆形" fill="#18D6FF" cx="13.5585586" cy="33.1081081" rx="1.26126126" ry="1"></ellipse>
<ellipse id="椭圆形" fill="#18D6FF" cx="18.9189189" cy="33.1081081" rx="1.26126126" ry="1"></ellipse>
<ellipse id="椭圆形" fill="#18D6FF" cx="23.963964" cy="33.1081081" rx="1.26126126" ry="1"></ellipse>
<g id="编组" transform="translate(12.297297, 21.441441)" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.26126126">
<polyline id="路径-45" points="0 0 2.43243243 0 5.67567568 5.67567568 8.10810811 5.67567568"></polyline>
<polyline id="路径-45" transform="translate(4.054054, 2.837838) scale(-1, 1) translate(-4.054054, -2.837838) " points="0 0 2.43243243 0 5.67567568 5.67567568 8.10810811 5.67567568"></polyline>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 726 B

@ -2,16 +2,12 @@
import tkinter as tk import tkinter as tk
from tkinter import * from tkinter import *
from tkinter import messagebox from tkinter import messagebox
from data_crud_sqlite import * # from data_crud import *
from data_crud import *
from data_line import Line_Right, line_draw, Useless_line from data_line import Line_Right, line_draw, Useless_line
from data_dispose_CR import Show_Right_All
from data_envelop import EnvelopMove, revise_objshow, order_array
# 图片常量 from data_dispose_CR import Show_Right_All
# img_host = PhotoImage(file='../images/主机_2.png') from data_envelop import EnvelopMove
# img_router = PhotoImage(file='../images/路由器_2.png')
# img_envelop = PhotoImage(file='../images/信封_2.png')
# img_detail = PhotoImage(file='../images/详情头_2.png')
# 创建父窗口函数 # 创建父窗口函数
class Main_Gui(): class Main_Gui():
@ -22,15 +18,12 @@ class Main_Gui():
# 创建窗口界面 # 创建窗口界面
def Set_init_window(self): def Set_init_window(self):
init_window_name = self.init_window_name init_window_name = self.init_window_name
'''头歌虚拟平台上的屏幕长宽大概为: 宽:1360;高:690''' root_width = init_window_name.winfo_screenwidth() # 获取window屏幕宽度
# root_width = init_window_name.winfo_screenwidth() # 获取window屏幕宽度
root_width = 1360
self.root_width = int(root_width / 4 * 3) # 设置父窗口界面宽度 self.root_width = int(root_width / 4 * 3) # 设置父窗口界面宽度
# print('父窗口界面宽度:'+str(self.root_width)) # 输出父窗口界面宽度 print('父窗口界面宽度:'+str(self.root_width)) # 输出父窗口界面宽度
# root_height = init_window_name.winfo_screenheight() # 获取window屏幕长度 root_height = init_window_name.winfo_screenheight() # 获取window屏幕长度
root_height = 690
self.root_height = int(root_height / 4 * 3) # 设置父窗口界面长度 self.root_height = int(root_height / 4 * 3) # 设置父窗口界面长度
# print('父窗口界面长度:'+str(self.root_height)) # 输出父窗口界面长度 print('父窗口界面长度:'+str(self.root_height)) # 输出父窗口界面长度
init_window_name.title('数据封包和解包模拟&X1-X4') # 标题 init_window_name.title('数据封包和解包模拟&X1-X4') # 标题
# 将窗口固定在屏幕中央 # 将窗口固定在屏幕中央
init_window_name.geometry(str(self.root_width)+'x'+str(self.root_height)+'+'+str(int((root_width-self.root_width)/2))+'+'+str(int((root_height-self.root_height)/2))) # 窗口大小 init_window_name.geometry(str(self.root_width)+'x'+str(self.root_height)+'+'+str(int((root_width-self.root_width)/2))+'+'+str(int((root_height-self.root_height)/2))) # 窗口大小
@ -39,7 +32,6 @@ class Main_Gui():
filemenu = Menu(main_menu, tearoff=False) # 设置子菜单 filemenu = Menu(main_menu, tearoff=False) # 设置子菜单
filemenu.add_command(label='启动模拟', command=self.similar_packet) #模拟函数未完成 filemenu.add_command(label='启动模拟', command=self.similar_packet) #模拟函数未完成
filemenu.add_command(label='启动X4模拟', command=self.similar_packet_X4) # 需要建立函数
filemenu.add_command(label='查找', command=quit) # 寻址功能函数未完成 filemenu.add_command(label='查找', command=quit) # 寻址功能函数未完成
filemenu.add_separator() # 画线 filemenu.add_separator() # 画线
filemenu.add_command(label='退出', command=quit) # 点击关闭页面 filemenu.add_command(label='退出', command=quit) # 点击关闭页面
@ -52,22 +44,20 @@ class Main_Gui():
self.cv = tk.Canvas(init_window_name, self.cv = tk.Canvas(init_window_name,
bg='#f0f0f0', bg='#f0f0f0',
# bg='white', # bg='white',
width=self.root_width-250, width=self.root_width-300,
height=self.root_height-150) height=self.root_height-180)
self.cv.pack(side=tk.LEFT, anchor=tk.NW) self.cv.pack(side=tk.LEFT, anchor=tk.NW)
# self.cv.grid(row=0, column=0) # self.cv.grid(row=0, column=0)
# self.cv.pack(anchor=tk.NW) # self.cv.pack(anchor=tk.NW)
# 画出包含仿真对象图的方框图 # 画出包含仿真对象图的方框图
self.cv.create_rectangle(100, 40, self.root_width - 250, self.root_height - 150, width=3, self.cv.create_rectangle(140, 80, self.root_width - 300, self.root_height - 180, width=3,
outline="#7f6000") # 这个位置可能需要修改 outline="#7f6000") # 这个位置可能需要修改
# 创建固定在左侧的标识符图像 # 创建固定在左侧的标识符图像
self.cv.create_image(50, 80, image=img_host) # 固定在左侧的主机对象 self.cv.create_image(80, 150, image=img_host) # 固定在左侧的主机对象
self.cv.create_text(50, 110, text='主机', font=('蔚然雅黑', 14, 'bold'), fill='black') self.cv.create_text(80, 180, text='主机对象', font=('蔚然雅黑', 14, 'bold'), fill='black')
self.cv.create_image(50, 160, image=img_router) # 固定在该canvas画布上的对象 == 路由器 self.cv.create_image(80, 280, image=img_router) # 固定在该canvas画布上的对象 == 路由器
self.cv.create_text(50, 190, text='路由器', font=('蔚然雅黑', 14, 'bold'), fill='black') self.cv.create_text(80, 310, text='路由器对象', font=('蔚然雅黑', 14, 'bold'), fill='black')
'''创建窗口前先将数据表simhost的数据恢复原样'''
revise_objshow('A','D')
'''画出仿真移动对象的图''' '''画出仿真移动对象的图'''
self.Show_Canvas_Right() # 未完成 self.Show_Canvas_Right() # 未完成
@ -78,112 +68,11 @@ class Main_Gui():
self.under_show_all() # 未完成 self.under_show_all() # 未完成
def similar_packet_X4(self):
# 删除窗口中的所有数据
self.right_on_text.delete('1.0', tk.END)
self.right_under_text.delete('1.0', tk.END)
self.under_text.delete('1.0', tk.END)
self.cv.delete('detail');self.cv.delete('line')
# self.cv.unbind("<Button-1>",self.Mouse) # 清楚鼠标点击事件,修改中还未完成 2023-7-25
self.open_envelop = False # 好像忘记了这个的作用了
self.packet_emu_X4 = tk.Toplevel()
self.packet_emu_X4.title('X4-启动模拟')
self.packet_emu_X4.geometry('300x200+800+200')
# 建立数据模拟数据的输入框字体
label_emu_x4_1 = tk.Label(self.packet_emu_X4, text='发送主机:').grid(row=0, pady=5)
label_emu_x4_2 = tk.Label(self.packet_emu_X4, text='接收主机:').grid(row=1, pady=5)
label_emu_x4_3 = tk.Label(self.packet_emu_X4, text='数据内容:').grid(row=2, pady=5)
label_emu_x4_4 = tk.Label(self.packet_emu_X4, text='数据大小(kb):').grid(row=3, pady=5)
label_emu_x4_5 = tk.Label(self.packet_emu_X4, text='数据标签:').grid(row=4, pady=5)
# 建立输入框
self.entry_emu_x4_1 = tk.Entry(self.packet_emu_X4)
self.entry_emu_x4_1.grid(row=0, column=1)
self.entry_emu_x4_2 = tk.Entry(self.packet_emu_X4)
self.entry_emu_x4_2.grid(row=1, column=1)
self.entry_emu_x4_3 = tk.Entry(self.packet_emu_X4)
self.entry_emu_x4_3.grid(row=2, column=1)
self.entry_emu_x4_4 = tk.Entry(self.packet_emu_X4)
self.entry_emu_x4_4.grid(row=3, column=1)
self.entry_emu_x4_5 = tk.Entry(self.packet_emu_X4)
self.entry_emu_x4_5.grid(row=4, column=1)
button_emu_left_X4 = tk.Button(self.packet_emu_X4, text='开启模拟', command=self.openpack_btn_x4).grid(row=5) # 函数未完成 2023-7-25
return None
# 设置X4模拟点击按钮后的函数
def openpack_btn_x4(self):
# 先获取点击按钮后输入框中的数据
entry_emu_x4_data_1 = self.entry_emu_x4_1.get()
entry_emu_x4_data_2 = self.entry_emu_x4_2.get()
entry_emu_x4_data_3 = self.entry_emu_x4_3.get()
entry_emu_x4_data_4 = self.entry_emu_x4_4.get()
entry_emu_x4_data_5 = self.entry_emu_x4_5.get()
select_objlable = Select_ObjShow() # 查询数据库索取所有数据
if entry_emu_x4_data_1=='' or entry_emu_x4_data_2=='' or entry_emu_x4_data_3==''or entry_emu_x4_data_4=='' or entry_emu_x4_data_5=='':
self.packet_emu_X4.destroy()
messagebox.showinfo('Error', '数据不能为空')
'''这个地方还需要添加一些其他的判断条件,暂且搁置'''
else:
self.packet_emu_X4.destroy() # 关闭启动模拟窗口
self.AppPackTag_Data_X4 = {
'SendHost': entry_emu_x4_data_1, 'ReceHost': entry_emu_x4_data_2, 'AppPackID': entry_emu_x4_data_3, 'AppPackSize': entry_emu_x4_data_4, 'AppPackTag': entry_emu_x4_data_5
}
# print(self.AppPackTag_Data_X4)
self.move_number_x4 = int(self.AppPackTag_Data_X4['AppPackSize']) / 2048
if self.move_number_x4 > 0 and self.move_number_x4 < 1:
self.move_number_x4 = 1
elif self.move_number_x4 % 1 != 0:
self.move_number_x4 = int(self.move_number_x4 + 1)
# print('需要拆分成的数据包数量:'+str(self.move_number_x4))
'''这个位置添加一个函数,通过获取的发送主机和接收主机的地址来修改数据库中ObjShow列中的数据'''
self.revise_objshow = revise_objshow(send_host=self.AppPackTag_Data_X4['SendHost'], reception_host=self.AppPackTag_Data_X4['ReceHost'])
'''这个位置调用信封移动的函数试试 PS:如果对象是如D——>A的则需要修改对象'''
# 如果需要修改数据之类的
self.envelop_move_x4()
return None
def envelop_move_x4(self):
'''在移动信封的同时需要设置在最下方显示进度提示,在最右边显示完成进度'''
'''建立一个暂时的变量,可以替换'''
self.unpacket = 0
self.location_all_x4 = [] # 定义用来存放对象的位置
self.Select_ObjID = Select_ObjID(self.revise_objshow)
for item in self.Select_ObjID:
# print(item)
ObjX = item['ObjX'];ObjY = item['ObjY'];ObjID = item['ObjID'];ObjType = item['ObjType']
location = (ObjX, ObjY, ObjID, ObjType)
self.location_all_x4.append(location)
'''这个位置需要添加一个判断来判断是否需要将数组倒序'''
self.location_all_x4 = order_array(self.location_all_x4,self.AppPackTag_Data_X4['SendHost'],self.AppPackTag_Data_X4['ReceHost'])
# print(self.location_all_x4)
# 实现信封移动并在实现的同时使最下方和最右方的canvas中显示数据
'''这个位置需要通过获取的对象来获取值'''
# self.ObjShow_1_data = Select_ObjShow()
self.show_envelop = EnvelopMove(cv=self.cv, img_host=img_host, img_router=img_router, img_envelop=img_envelop,
img_detail=img_detail, move_data=self.location_all_x4, unpacket=self.unpacket,
move_number=self.move_number_x4, right_on_text=self.right_on_text,
Objshow_data=self.Select_ObjID, AppPackTag_Data=self.AppPackTag_Data_X4,
right_under_text=self.right_under_text, under_text=self.under_text)
self.show_envelop.main_envelop()
self.Mouse = self.show_envelop.Mouse_Event()
# self.show_envelop.show_data_move()
# print(self.ObjShow_1_data)
# print(self.location_all)
return None
'''# 设置一个编写类封包函数''' '''# 设置一个编写类封包函数'''
def similar_packet(self): def similar_packet(self):
self.right_on_text.delete('1.0', tk.END) self.right_on_text.delete('1.0', tk.END)
self.right_under_text.delete('1.0', tk.END) self.right_under_text.delete('1.0', tk.END)
self.under_text.delete('1.0', tk.END) self.under_text.delete('1.0', tk.END)
self.cv.delete('detail');self.cv.delete('line')
# self.cv.unbind("<Button-1>", self.Mouse)
# 定义一个值用来处理信封移动事件的开启 # 定义一个值用来处理信封移动事件的开启
self.open_envelop = False self.open_envelop = False
# 建立一个子窗口完成数据 # 建立一个子窗口完成数据
@ -236,14 +125,14 @@ class Main_Gui():
'AppPackSize': entry_emu_2_data, 'AppPackSize': entry_emu_2_data,
'AppPackTag': entry_emu_3_data 'AppPackTag': entry_emu_3_data
} }
# print(self.AppPackTag_Data) print(self.AppPackTag_Data)
'''这里获取需要循环发送信封的次数''' '''这里获取需要循环发送信封的次数'''
self.move_number = int(self.AppPackTag_Data['AppPackSize']) / 2048 self.move_number = int(self.AppPackTag_Data['AppPackSize']) / 2048
if self.move_number > 0 and self.move_number < 1: if self.move_number > 0 and self.move_number < 1:
self.move_number = 1 self.move_number = 1
elif self.move_number % 1 != 0: elif self.move_number % 1 != 0:
self.move_number = int(self.move_number + 1) self.move_number = int(self.move_number + 1)
# print('需要拆分成的数据包数量:'+str(self.move_number)) print('需要拆分成的数据包数量:'+str(self.move_number))
# print(self.host_date) # print(self.host_date)
# '''首先先建立一个判断两个主机之间是否存在通信的可能''' # '''首先先建立一个判断两个主机之间是否存在通信的可能'''
# 建立一个数组用来存储需要循环显示的数据 # 建立一个数组用来存储需要循环显示的数据
@ -264,13 +153,11 @@ class Main_Gui():
ObjX = item['ObjX'];ObjY = item['ObjY'];ObjID = item['ObjID'];ObjType = item['ObjType'] ObjX = item['ObjX'];ObjY = item['ObjY'];ObjID = item['ObjID'];ObjType = item['ObjType']
location = (ObjX, ObjY, ObjID, ObjType) location = (ObjX, ObjY, ObjID, ObjType)
self.location_all.append(location) self.location_all.append(location)
# print(self.location_all)
# 实现信封移动并在实现的同时使最下方和最右方的canvas中显示数据 # 实现信封移动并在实现的同时使最下方和最右方的canvas中显示数据
self.show_envelop = EnvelopMove(cv=self.cv,img_host=img_host, img_router=img_router, img_envelop=img_envelop,img_detail=img_detail,move_data=self.location_all,unpacket=self.unpacket, self.show_envelop = EnvelopMove(cv=self.cv,img_host=img_host, img_router=img_router, img_envelop=img_envelop,img_detail=img_detail,move_data=self.location_all,unpacket=self.unpacket,
move_number=self.move_number,right_on_text=self.right_on_text,Objshow_data=self.ObjShow_1_data,AppPackTag_Data=self.AppPackTag_Data, move_number=self.move_number,right_on_text=self.right_on_text,Objshow_data=self.ObjShow_1_data,AppPackTag_Data=self.AppPackTag_Data,
right_under_text=self.right_under_text,under_text=self.under_text) right_under_text=self.right_under_text,under_text=self.under_text)
self.show_envelop.main_envelop() self.show_envelop.main_envelop()
self.Mouse = self.show_envelop.Mouse_Event()
# self.show_envelop.show_data_move() # self.show_envelop.show_data_move()
# print(self.ObjShow_1_data) # print(self.ObjShow_1_data)
# print(self.location_all) # print(self.location_all)
@ -281,7 +168,7 @@ class Main_Gui():
self.simhost_all_data = get_simhost_alldata() # 获取simhost表中的所有数据 self.simhost_all_data = get_simhost_alldata() # 获取simhost表中的所有数据
# print(self.simhost_all_data) # print(self.simhost_all_data)
self.ObjShow_1_data = Select_ObjShow() # 采集所有ObjShow为1的数据 self.ObjShow_1_data = Select_ObjShow() # 采集所有ObjShow为1的数据
# print(self.ObjShow_1_data) print(self.ObjShow_1_data)
self.line_data = line_draw(self.ObjShow_1_data) self.line_data = line_draw(self.ObjShow_1_data)
# print(self.line_data) # print(self.line_data)
'''外接画线函数''' '''外接画线函数'''
@ -301,13 +188,11 @@ class Main_Gui():
self.right_on_label = tk.Label(self.init_window_name, text='发送主机详情:',font=('蔚然雅黑', 12, 'bold')) self.right_on_label = tk.Label(self.init_window_name, text='发送主机详情:',font=('蔚然雅黑', 12, 'bold'))
# self.right_on_label.pack(side=tk.TOP, fill=tk.Y, padx=10, pady=10) # self.right_on_label.pack(side=tk.TOP, fill=tk.Y, padx=10, pady=10)
self.right_on_label.pack(anchor=tk.NW, fill=tk.Y, padx=5, pady=5) self.right_on_label.pack(anchor=tk.NW, fill=tk.Y, padx=5, pady=5)
# self.right_on_text = tk.Text(self.init_window_name, width=29, height=13) self.right_on_text = tk.Text(self.init_window_name, width=40, height=22)
self.right_on_text = tk.Text(self.init_window_name, width=24, height=10)
self.right_on_text.pack(anchor=tk.NW, fill=tk.Y, padx=5, pady=5) self.right_on_text.pack(anchor=tk.NW, fill=tk.Y, padx=5, pady=5)
self.right_under_label = tk.Label(self.init_window_name, text='接收主机详情:', font=('蔚然雅黑', 12, 'bold')) self.right_under_label = tk.Label(self.init_window_name, text='接收主机详情:', font=('蔚然雅黑', 12, 'bold'))
self.right_under_label.pack(anchor=tk.NW, fill=tk.Y, padx=5, pady=5) self.right_under_label.pack(anchor=tk.NW, fill=tk.Y, padx=5, pady=5)
# self.right_under_text = tk.Text(self.init_window_name, width=29, height=13) self.right_under_text = tk.Text(self.init_window_name, width=40, height=22)
self.right_under_text = tk.Text(self.init_window_name, width=24, height=10)
self.right_under_text.pack(anchor=tk.NW, fill=tk.Y, padx=5, pady=5) self.right_under_text.pack(anchor=tk.NW, fill=tk.Y, padx=5, pady=5)
self.right_on_text.configure(font=("TkDefaultFont", 12)) self.right_on_text.configure(font=("TkDefaultFont", 12))
self.right_under_text.configure(font=("TkDefaultFont", 12)) self.right_under_text.configure(font=("TkDefaultFont", 12))
@ -334,16 +219,15 @@ class Main_Gui():
def under_show_all(self): def under_show_all(self):
'''更换方式显示''' '''更换方式显示'''
scrollbar_y = tk.Scrollbar(self.init_window_name) scrollbar_y = tk.Scrollbar(self.init_window_name)
scrollbar_y.place(x=760, y=380,relheight=0.25) scrollbar_y.place(x=1130, y=638,relheight=0.21)
# scrollbar_x = tk.Scrollbar(self.init_window_name, orient=tk.HORIZONTAL) # scrollbar_x = tk.Scrollbar(self.init_window_name, orient=tk.HORIZONTAL)
# scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X) # scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
self.under_label = tk.Label(self.init_window_name, text='数据传输: ', font=('蔚然雅黑', 12, 'bold')) self.under_label = tk.Label(self.init_window_name, text='数据传输进度: ', font=('蔚然雅黑', 12, 'bold'))
# self.under_label.pack(side=tk.BOTTOM, anchor=tk.SW) # self.under_label.pack(side=tk.BOTTOM, anchor=tk.SW)
self.under_label.place(x=10, y=375) self.under_label.place(x=20, y=638)
# self.under_text = tk.Text(self.init_window_name, width=82, height=8) self.under_text = tk.Text(self.init_window_name, width=123, height=10)
self.under_text = tk.Text(self.init_window_name, width=65, height=8)
# self.under_text.place(x=140, y=638, relheight=1) # self.under_text.place(x=140, y=638, relheight=1)
self.under_text.place(x=100, y=375) self.under_text.place(x=140, y=638)
self.under_text.configure(font=("TkDefaultFont", 12)) self.under_text.configure(font=("TkDefaultFont", 12))
scrollbar_y.config(command=self.under_text.yview) scrollbar_y.config(command=self.under_text.yview)
self.under_text.config(yscrollcommand=scrollbar_y.set) self.under_text.config(yscrollcommand=scrollbar_y.set)
@ -363,19 +247,10 @@ class Main_Gui():
if __name__ == '__main__': if __name__ == '__main__':
init_Windows = tk.Tk() # 创建一个父窗口 init_Windows = tk.Tk() # 创建一个父窗口
create_simhost() img_host = PhotoImage(file='./images/主机_1.png')
create_ipaddr() img_router = PhotoImage(file='./images/路由器_1.png')
insert_simhost() img_envelop = PhotoImage(file='./images/信封_1.png')
insert_ipaddr() img_detail = PhotoImage(file='./images/详情头_1.png')
img_host = PhotoImage(file='/data/workspace/myshixun/images/主机_2.png')
img_router = PhotoImage(file='/data/workspace/myshixun/images/路由器_2.png')
img_envelop = PhotoImage(file='/data/workspace/myshixun/images/信封_2.png')
img_detail = PhotoImage(file='/data/workspace/myshixun/images/详情头_2.png')
# img_host = PhotoImage(file='../images/主机_2.png')
# img_router = PhotoImage(file='../images/路由器_2.png')
# img_envelop = PhotoImage(file='../images/信封_2.png')
# img_detail = PhotoImage(file='../images/详情头_2.png')
Gui = Main_Gui(init_Windows) Gui = Main_Gui(init_Windows)
Gui.Set_init_window() Gui.Set_init_window()
print('程序运行成功!')
init_Windows.mainloop() init_Windows.mainloop()

@ -0,0 +1,107 @@
import socket
import struct
def format_mac_address(mac_bytes):
"""
Format a MAC address from bytes to a human-readable string.
Args:
mac_bytes (bytes): The MAC address in bytes format.
Returns:
str: The MAC address in human-readable format.
"""
mac_str = mac_bytes.hex()
mac_formatted = ':'.join(mac_str[i:i+2] for i in range(0, 12, 2))
return mac_formatted
class AgreementUtil():
@staticmethod
def create_udp_packet(data, dest_port, src_port):
"""
创建UDP数据包
Returns:
bytes: `UDP数据包`.
"""
# UDP header fields
udp_header = struct.pack('!HHHH', src_port, dest_port, 8 + len(data), 0) # Length includes header length
return udp_header + data.encode()
@staticmethod
def create_ip_packet(udp_packet, dest_ip, src_ip):
"""
创建IP数据包
Returns:
bytes: IP数据包
"""
# IP header fields
version = 4
ihl = 5 # Internet Header Length
type_of_service = 0
total_length = 20 + len(udp_packet) # 20 bytes IP header + UDP packet length
identification = 54321
flags = 0 # Don't fragment
fragment_offset = 0
ttl = 64 # Time to live
protocol = 17 # UDP
checksum = 0 # For simplicity, set to 0
source_ip = socket.inet_aton(src_ip)
dest_ip = socket.inet_aton(dest_ip)
# IP数据包头部字段
ip_header = struct.pack('!BBHHHBBH4s4s',
(version << 4) + ihl, type_of_service, total_length,
identification, (flags << 13) + fragment_offset,
ttl, protocol, checksum, source_ip, dest_ip)
return ip_header + udp_packet
@staticmethod
def create_ethernet_frame(ip_packet, dest_mac, src_mac):
"""
创建以太网帧数据包
Returns:
bytes: 以太网帧数据包
"""
# Convert MAC addresses from string format to bytes
dest_mac_bytes = bytes.fromhex(dest_mac.replace(':', ''))
src_mac_bytes = bytes.fromhex(src_mac.replace(':', ''))
# Ethernet type for IP (0x0800)
ethernet_type = 0x0800
# Pack Ethernet frame fields
ethernet_frame = struct.pack('!6s6sH', dest_mac_bytes, src_mac_bytes, ethernet_type)
return ethernet_frame + ip_packet
@staticmethod
def parse_ethernet_frame(frame):
"""
解析以太网帧数据包
Returns: 发送端MAC接收端MAC以太网类型IP数据包
"""
dest_mac, src_mac, ethertype = struct.unpack('!6s6sH', frame[:14])
payload = frame[14:]
return format_mac_address(src_mac), format_mac_address(dest_mac), ethertype, payload
@staticmethod
def parse_ip_packet(packet):
"""
解析 IP 数据包
Returns: 发送端IP接收端IP协议UDP数据包
"""
version_ihl, type_of_service, total_length, identification, flags_fragment_offset, \
ttl, protocol, checksum, source_ip, dest_ip = struct.unpack('!BBHHHBBH4s4s', packet[:20])
payload = packet[20:]
return socket.inet_ntoa(source_ip), socket.inet_ntoa(dest_ip), protocol, payload
@staticmethod
def parse_udp_packet(packet):
"""
解析UDP数据包
Returns:
tuple: 发送主机端口接收主机端口数据
"""
src_port, dest_port, length, checksum = struct.unpack('!HHHH', packet[:8])
data = packet[8:]
return src_port, dest_port, data.decode()

@ -0,0 +1,421 @@
import ipaddress
import sys
import threading
from tkinter import filedialog
from SimUtil import *
from SimObjs import SimPacket, SimHost, AllSimConnect, SimRouter, SimSwitch, SimHub, SimBase
from dbUtil import search, execute_sql, delete_obj, truncate_db
from PIL import Image as imim
from packet import *
class Message(Canvas):
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)
self.message = []
self.master = master
self.scrollbar_y = tk.Scrollbar(master, orient="vertical", command=self.yview)
self.scrollbar_y.pack(side="right", fill=BOTH)
self.scrollbar_x = tk.Scrollbar(master, orient=HORIZONTAL, command=self.xview)
self.scrollbar_x.pack(side="bottom", fill=BOTH)
self.config(yscrollcommand=self.scrollbar_y.set, xscrollcommand=self.scrollbar_x.set)
def show_message(self, message, color="#5fa8fe"):
for mes in message.split("\n"):
self.message.append({"message": mes, "color": color})
num = 0
self.delete("message")
for function in self.message:
self.create_text(20, 25 * num + 10, anchor="nw", text=function["message"], font=("", 15),
fill=function["color"], tags="message")
num += 1
self.update()
self.configure(scrollregion=self.bbox("all"))
self.scrollbar_y.set(1.0, 1.0)
self.yview_moveto(1.0)
class NetWorkAnalog(Canvas):
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)
self.master = master
self.router_img = ImageTk.PhotoImage(
Image.open(sys.path[0] + "/../datas/images/路由器@2x.png").resize((40, 40)))
self.switch_img = ImageTk.PhotoImage(
Image.open(sys.path[0] + "/../datas/images/交换机@2x.png").resize((40, 40)))
self.hub_img = ImageTk.PhotoImage(
Image.open(sys.path[0] + "/../datas/images/集线器@2x.png").resize((40, 40)))
self.host_img = ImageTk.PhotoImage(
Image.open(sys.path[0] + "/../datas/images/主机@2x.png").resize((40, 40)))
self.width = int(self.cget("width"))
self.height = int(self.cget("height"))
self.canvas_size = [150, 0, int(self.width * 0.8), int(self.height * 0.8)]
self.label_top_img = ImageTk.PhotoImage(imim.open("../datas/images/右上框@2x.png").resize((int(self.width - self.width * 0.85), int(self.canvas_size[3] * 0.4))))
self.label_bottom_img = ImageTk.PhotoImage(imim.open("../datas/images/右下框@2x.png").resize((int(self.width - self.width * 0.85), int(self.canvas_size[3] * 0.45))))
self.message_img = ImageTk.PhotoImage(
Image.open(sys.path[0] + "/../datas/images/日志消息展示框@2x.png").resize((self.width - 60, self.height - self.canvas_size[3] - 30))
)
self.text_back_img = ImageTk.PhotoImage(
Image.open("../images/文字背景@3x.png").resize((155, 90))
)
message_frame = Frame(self, width=self.width - 60, height=self.height - self.canvas_size[3] - 30)
message_frame.place(x=15, y=self.canvas_size[3] + 15, anchor=NW)
self.message = Message(message_frame, width=self.width - 60, height=self.height - self.canvas_size[3] - 30)
self.message.pack()
self.message.configure(bg="#edf8ff")
self.configure(bg="#ddeafe")
self.filename = ImageTk.PhotoImage(imim.open("../datas/images/背景@2x.png").resize((self.width, self.canvas_size[3])))
self.create_image(0, 0, image=self.filename, anchor=NW)
self.chose = self.host_img
self.AllSimObjs = {}
self.conns = []
self.drawLine = True # 画线标志
self.line_start_obj = None
self.line_end_obj = None
self.line_start_ifs = None
self.line_end_ifs = None
self.chose_obj = None
self.show_label_flag = True
self.show_interface_flag = True
self.trans_obj = set()
self.create_widget()
def is_chose(self):
"""
当被选中时绘制选中框
:return:
"""
self.delete("rectangle")
self.create_rectangle(self.chose_obj.ObjX - 35, self.chose_obj.ObjY - 35, self.chose_obj.ObjX + 15,
self.chose_obj.ObjY + 15, outline="red", tags="rectangle")
def reload_data(self):
# todo: 加载上一次程序运行的数据
"""
加载上一次程序运行时的数据
:return:
"""
self.AllSimObjs = {}
self.conns = []
sim_obj_sql = "select * from sim_objs"
sim_obj_data = search(sim_obj_sql)
for index, row in sim_obj_data.iterrows(): # 初始化组件对象
sim_type = row["ObjType"]
ObjX = row["ObjX"]
ObjY = row["ObjY"]
ConfigCorrect = row["ConfigCorrect"]
ObjLable = row["ObjLabel"]
ObjID = row["ObjID"]
if sim_type == 1:
tag = SimHost(self, ObjX, ObjY, ObjID, ConfigCorrect, ObjLable)
elif sim_type == 2:
tag = SimRouter(self, ObjX, ObjY, ObjID, ConfigCorrect, ObjLable)
elif sim_type == 3:
tag = SimSwitch(self, ObjX, ObjY, ObjID, ConfigCorrect, ObjLable)
else:
tag = SimHub(self, ObjX, ObjY, ObjID, ConfigCorrect, ObjLable)
tag.create_img()
self.AllSimObjs[tag.ObjID] = tag
sim_conn_sql = "select s.conn_id, ConfigCorrect, node_id, node_ifs from sim_conn s join conn_config c on s.conn_id=c.conn_id"
sim_conn_data = search(sim_conn_sql)
conn_datas = {}
for index, conn in sim_conn_data.iterrows():
if (conn["conn_id"], conn["ConfigCorrect"]) not in conn_datas:
conn_datas[(conn["conn_id"], conn["ConfigCorrect"])] = [(conn["node_id"], conn["node_ifs"])]
else:
conn_datas[(conn["conn_id"], conn["ConfigCorrect"])].append((conn["node_id"], conn["node_ifs"]))
for key, value in conn_datas.items():
conn_obj = AllSimConnect(self, self.AllSimObjs[value[0][0]], value[0][1],
self.AllSimObjs[value[1][0]], value[1][1], key[1])
conn_obj.draw_line()
self.AllSimObjs[value[0][0]].connections[value[0][1] - 1] = conn_obj # 将连接对象传入组件对象
self.AllSimObjs[value[1][0]].connections[value[1][1] - 1] = conn_obj
self.conns.append(conn_obj)
conn_obj.ConfigCorrect = key[1]
def show_obj(self, AllSimObj, conns):
self.AllSimObjs = AllSimObj
self.conns = conns
for key, sim_obj in self.AllSimObjs.items():
sim_obj.create_img()
for conn in self.conns:
conn.draw_line()
def send_packet(self):
"""
发送数据包
:return:
"""
hosts = {}
for key, tag in self.AllSimObjs.items():
if tag.ObjType == 1 and tag.ConfigCorrect == 1:
hosts[tag.ObjLabel] = tag.ObjID
child2 = tk.Toplevel()
child2.title("数据包配置")
child2.geometry('392x306+200+110')
child2.grab_set() # 设置组件焦点抓取。使焦点在释放之前永远保持在这个组件上,只能在这个组件上操作
tk.Label(child2, text='发送主机:', font=('黑体', 16)).grid(row=0, column=0, columnspan=2, sticky='w', pady=10)
send_host = StringVar()
host_combobox = ttk.Combobox(
master=child2, # 父容器
height=5, # 高度,下拉显示的条目数量
width=18, # 宽度
state='readonly', # readonly(只可选)
font=('', 16), # 字体
textvariable=send_host, # 通过StringVar设置可改变的值
values=list(hosts.keys()), # 设置下拉框的选项
)
host_combobox.grid(row=0, column=1, pady=10)
tk.Label(child2, text='接收主机:', font=('黑体', 16)).grid(row=1, column=0, sticky='w', pady=10) # ,sticky='w'靠左显示
receive_host = StringVar()
ttk.Combobox(
master=child2, # 父容器
height=5, # 高度,下拉显示的条目数量
width=18, # 宽度
state='readonly', # readonly(只可选)
font=('', 16), # 字体
textvariable=receive_host, # 通过StringVar设置可改变的值
values=list(hosts.keys()), # 设置下拉框的选项
).grid(row=1, column=1, pady=10)
tk.Label(child2, text='数据大小(kb):', font=('黑体', 16)).grid(row=2, column=0, sticky='w',
pady=10) # ,sticky='w'靠左显示
packet_size = tk.Entry(child2, font=('黑体', 16), textvariable=tk.StringVar())
packet_size.grid(row=2, column=1, pady=10)
tk.Label(child2, text='数据标签:', font=('黑体', 16)).grid(row=3, column=0, sticky='w',
pady=10) # ,sticky='w'靠左显示
packet_label = tk.Entry(child2, font=('黑体', 16), textvariable=tk.StringVar())
packet_label.grid(row=3, column=1, pady=10)
def send():
"""
发送数据包
:return:
"""
if send_host.get() == "" or receive_host.get() == "" or packet_size.get() == "" or packet_label.get() == "":
messagebox.showerror("注意", message="信息不能为空")
return
if send_host.get() == receive_host.get():
messagebox.showerror("注意", message="发送主机和接收主机不能相同!")
send_message = """发送主机:{}\n\nIP地址{}\n\nMac地址{}\n\n发送数据包大小:{}\n\n已发送数据数量:{}\n\n需要发送的数据包总数:{}"""
receive_message = """接收主机:{}\n\nIP地址{}\n\nMac地址{}\n\n发送数据包大小:{}\n\n已接收数据数量:{}\n\n需要发送的数据包总数:{}"""
send_host_obj = self.AllSimObjs[hosts[send_host.get()]]
receive_host_obj = self.AllSimObjs[hosts[receive_host.get()]]
pack_label = packet_label.get()
pack_size = packet_size.get()
child2.destroy()
count = split_appdata(int(pack_size))
self.show_top_message(send_host_obj,
message=send_message.format(send_host_obj.ObjLabel, send_host_obj.interface[0]["ip"],
send_host_obj.interface[0]["mac"], pack_size, 0, count))
self.show_bottom_message(receive_host_obj, message=receive_message.format(receive_host_obj.ObjLabel,
receive_host_obj.interface[0][
"ip"],
receive_host_obj.interface[0][
"mac"], pack_size, 0, count))
for obj in self.trans_obj:
self.delete(obj.ObjID + "detail_button")
self.delete(obj.ObjID + "detail")
self.unbind(obj.ObjID, "<Button-1>")
send_host_obj.create_packet(receive_host_obj, pack_label, pack_size)
tk.Button(child2, text='开启模拟', font=('黑体', 16), height=1, command=send).grid(row=5, column=0, sticky='e', pady=10)
tk.Button(child2, text='取消', font=('黑体', 16), height=1, command=child2.destroy).grid(row=5, column=1, sticky='e', pady=10)
# 建立画出对象详情的函数
def draw_detail(self, obj):
# 判断type对象来画出详情表
if obj.ObjType == 1: # 当type对象为1 画出主机详情图
app_color = ("#94D050", '#00B0F0')
trans_color = ("#94D050", '#00B0F0')
ip_color = ("#94D050", '#00B0F0')
mac_color = ("#94D050", '#00B0F0')
elif obj.ObjType == 2:
app_color = ("#D3D3D3", "#D3D3D3")
trans_color = ("#D3D3D3", "#D3D3D3")
ip_color = ("#94D050", '#00B0F0')
mac_color = ("#94D050", '#00B0F0')
elif obj.ObjType == 3:
app_color = ("#D3D3D3", "#D3D3D3")
trans_color = ("#D3D3D3", "#D3D3D3")
ip_color = ("#D3D3D3", "#D3D3D3")
mac_color = ("#94D050", '#00B0F0')
else:
app_color = ("#D3D3D3", "#D3D3D3")
trans_color = ("#D3D3D3", "#D3D3D3")
ip_color = ("#D3D3D3", "#D3D3D3")
mac_color = ("#94D050", '#00B0F0')
frist_x = obj.ObjX # 获取frist_x
frist_y = obj.ObjY # 获取frist_y
# 这里缺少一个删除其他详情的步骤
# 画出连接详情表的线
tag_id = obj.ObjID + "detail"
if len(self.gettags(tag_id)) > 0:
self.delete(tag_id)
else:
self.create_line((frist_x + 40, frist_y - 20), (frist_x + 80, frist_y - 20),
(frist_x + 90, frist_y - 60),
fill='#50abf8', tags=tag_id, width=2)
# 画出详情表
self.create_image(frist_x + 50, frist_y - 140, image=self.text_back_img, anchor=NW, tags=tag_id)
# 画出相应的绿条数据
self.create_text(frist_x + 70, frist_y - 130, text='应用层', tags=tag_id)
self.create_text(frist_x + 70, frist_y - 107, text='传输层', tags=tag_id)
self.create_text(frist_x + 70, frist_y - 84, text='IP 层', tags=tag_id)
self.create_text(frist_x + 70, frist_y - 62, text='链路层', tags=tag_id)
# 画出 右侧绿色和蓝色的类进度条
# 应用层
self.create_rectangle(frist_x + 197, frist_y - 135, frist_x + 170, frist_y - 120, fill=app_color[0],
outline=app_color[0], tags=tag_id)
self.create_rectangle(frist_x + 168, frist_y - 135, frist_x + 148, frist_y - 120, fill=app_color[1],
outline=app_color[1], tags=tag_id)
# 传输层
self.create_rectangle(frist_x + 197, frist_y - 115, frist_x + 160, frist_y - 100,
fill=trans_color[0],
outline=trans_color[0], tags=tag_id)
self.create_rectangle(frist_x + 158, frist_y - 115, frist_x + 133, frist_y - 100,
fill=trans_color[1],
outline=trans_color[1], tags=tag_id)
# IP 层
self.create_rectangle(frist_x + 197, frist_y - 93, frist_x + 150, frist_y - 78, fill=ip_color[0],
outline=ip_color[0], tags=tag_id)
self.create_rectangle(frist_x + 148, frist_y - 93, frist_x + 118, frist_y - 78, fill=ip_color[1],
outline=ip_color[1], tags=tag_id)
# 链路层
self.create_rectangle(frist_x + 197, frist_y - 70, frist_x + 133, frist_y - 55, fill=mac_color[0],
outline=mac_color[0], tags=tag_id)
self.create_rectangle(frist_x + 131, frist_y - 70, frist_x + 98, frist_y - 55, fill=mac_color[1],
outline=mac_color[1], tags=tag_id)
def trans_over(self, objs):
print("传输完成")
self.trans_obj = objs
for obj in objs:
obj.create_detail_button()
self.tag_bind(obj.ObjID, "<Button-1>", lambda event, obj=obj: self.draw_detail(obj)) # 绑定右击事件
obj.is_packet = False
obj.is_un_packet = False
def clear_canvas(self):
"""
清除画布
:return:
"""
ask = messagebox.askquestion(title='确认操作', message='确认要清除画布吗?')
if ask == "no":
return
truncate_db() # 清除数据库
for tag_id, tag in self.AllSimObjs.items():
self.delete(tag_id)
self.delete(tag_id + "text")
for conn in self.conns:
conn.delete_line()
self.delete("rectangle")
self.AllSimObjs.clear()
self.conns.clear()
def export_data(self):
try:
export = ExportUtil(sys.path[0] + "/database.xlsx")
export.export()
self.message.show_message("文件导出成功!文件位置在{}".format(sys.path[0] + "/database.xlsx"))
except Exception as E:
self.message.show_message(str(E), color="red")
def import_data(self):
truncate_db()
for tag_id, tag in self.AllSimObjs.items():
self.delete(tag_id)
self.delete(tag_id + "text")
for conn in self.conns:
conn.delete_line()
self.delete("rectangle")
self.AllSimObjs.clear()
self.conns.clear()
file_path = filedialog.askopenfilename()
if file_path:
export = ExportUtil(file_path)
export.import_data()
self.message.show_message("文件导入成功!")
self.reload_data()
def show_top_message(self, obj, message):
# todo: 显示网络配置信息
"""
显示网络配置信息
:return:
"""
self.delete("netSet")
self.create_text(self.width * 0.82 + 120, 80, text="(" + obj.ObjLabel + ")", anchor="n", font=('微软雅黑', 14, 'bold'),
fill="#7030a0", tags="netSet")
self.create_text(self.width * 0.82 + 20, 80 + 25, text=message,
anchor="nw", font=('宋体', 14), tags="netSet")
def show_bottom_message(self, obj, message):
# todo: 显示路由表交换表信息
"""
显示路由交换表信息
:return:
"""
self.delete("routerSet")
self.create_text(self.width * 0.82 + 120, self.canvas_size[3] / 2 + 50, text="(" + obj.ObjLabel + ")", anchor="n", font=('微软雅黑', 14, 'bold'),
fill="#7030a0", tags="routerSet")
self.create_text(self.width * 0.82 + 20, self.canvas_size[3] / 2 + 50 + 25, text=message,
anchor="nw", font=('宋体', 14), tags="routerSet")
def create_config_button(self):
# 创建一个菜单栏,这里我们可以把他理解成一个容器,在窗口的上方
menubar = tk.Menu(root)
# 定义一个空菜单单元
setMenu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label='发送数据包', menu=setMenu)
setMenu.add_command(label='发送数据包', command=self.send_packet)
menubar.add_command(label='清除屏幕', command=self.clear_canvas)
menubar.add_command(label='导出数据', command=self.export_data)
menubar.add_command(label='导入数据', command=self.import_data)
root.config(menu=menubar)
def create_widget(self):
# todo: 创建页面
"""
创建整体页面布局
:return:
"""
self.create_rectangle(self.canvas_size[0], self.canvas_size[1], self.canvas_size[2], self.canvas_size[3], outline="#7f6000", width=0) # 矩形框,左上角坐标,右下角坐标
self.create_image(self.width * 0.82, 30, image=self.label_top_img, anchor=NW) # 矩形框,左上角坐标,右下角坐标
self.create_text(self.width * 0.82 + 120, 30 + 15, text="发送主机详情", anchor="n", font=('微软雅黑', 18, 'bold'))
self.create_image(self.width * 0.82, self.canvas_size[3] / 2, image=self.label_bottom_img, anchor=NW) # 矩形框,左上角坐标,右下角坐标
# round_rectangle(self, self.width * 0.82, self.canvas_size[3] / 2, self.width * 0.98, self.canvas_size[3] - 30, outline="#ffff00", width=2, fill="#f4b88e") # 矩形框,左上角坐标,右下角坐标
self.create_text(self.width * 0.82 + 120, self.canvas_size[3] / 2 + 15, text="接收主机详情", anchor="n", font=('微软雅黑', 18, 'bold'))
# 显示左边的固定图片
img_height, text_height, split_width = 50, 40, 120
self.create_text(text_height, split_width + 40, text="路由器", anchor="nw", font=('微软雅黑', 18, 'bold')) # 显示文字
self.create_image(img_height, split_width, image=self.router_img, anchor="nw")
self.create_text(text_height, split_width * 2 + 40, text="交换机", anchor="nw", font=('微软雅黑', 18, 'bold')) # 显示文字
self.create_image(img_height, split_width * 2, image=self.switch_img, anchor="nw")
self.create_text(text_height, split_width * 3 + 40, text="集线器", anchor="nw", font=('微软雅黑', 18, 'bold')) # 显示文字
self.create_image(img_height, split_width * 3, image=self.hub_img, anchor="nw")
self.create_text(text_height, split_width * 4 + 40, text="主机", anchor="nw", font=('微软雅黑', 18, 'bold')) # 显示文字
self.create_image(img_height, split_width * 4, image=self.host_img, anchor="nw")
if __name__ == '__main__':
root = Window()
root.title('网络拓扑图')
screen_width = root.winfo_screenwidth() # winfo方法来获取当前电脑屏幕大小
screen_height = root.winfo_screenheight()
root_attr = {
"width": screen_width * 0.83,
"height": screen_height * 0.85,
}
size = '%dx%d+%d+%d' % (root_attr['width'], root_attr['height'], (screen_width - root_attr['width']) / 2,
(screen_height - root_attr['height']) / 2 - 30)
canvas = NetWorkAnalog(root, width=root_attr['width'], heigh=root_attr['height'], bg="white")
canvas.place(x=0, y=0, anchor='nw')
canvas.create_config_button()
canvas.reload_data()
root.geometry(size)
root.mainloop()

@ -0,0 +1,600 @@
import math
import sys
import threading
from time import sleep
from tkinter import Tk
from tkinter import messagebox
from ttkbootstrap import *
from uuid import uuid4
import ipaddress
import time
from PIL import ImageTk, Image, ImageFont
from dbUtil import search
from packet import *
pause_event = threading.Event()
class SimBase():
# todo: 组件父类
"""
图标类所有组件的父类
"""
def __init__(self, canvas, x, y, id, config=None, label=None):
self.ConfigCorrect = 0 if config is None else config # 是否进行配置
self.ObjType = None # 组件类型 1->主机2->路由器3->交换机4->集线器
self.ObjLabel = ""
self.ObjID = id
self.ObjX = x
self.ObjY = y
self.canvas = canvas
self.is_packet = False
self.is_un_packet = False
self.host_img = ImageTk.PhotoImage(
Image.open(sys.path[0] + "/../datas/images/主机@2x.png").resize((40, 40)))
self.host_img_tm = ImageTk.PhotoImage(
Image.open(sys.path[0] + "/../datas/images/主机--暗色@2x.png").resize((40, 40)))
self.router_img = ImageTk.PhotoImage(
Image.open(sys.path[0] + "/../datas/images/路由器@2x.png").resize((40, 40)))
self.router_img_tm = ImageTk.PhotoImage(
Image.open(sys.path[0] + "/../datas/images/路由器--暗色@2x.png").resize((40, 40)))
self.switch_img = ImageTk.PhotoImage(
Image.open(sys.path[0] + "/../datas/images/交换机@2x.png").resize((40, 40)))
self.switch_img_tm = ImageTk.PhotoImage(
Image.open(sys.path[0] + "/../datas/images/交换机--暗色@2x.png").resize((40, 40)))
self.hub_img = ImageTk.PhotoImage(
Image.open(sys.path[0] + "/../datas/images/集线器@2x.png").resize((40, 40)))
self.hub_img_tm = ImageTk.PhotoImage(
Image.open(sys.path[0] + "/../datas/images/集线器--暗色@2x.png").resize((40, 40)))
self.img = None
self.img_tm = None
self.interface = [{}, {}, {}, {}]
self.connections = ["1", "2", "3", "4"]
self.set_default_config()
self.packet_window = None
def set_default_name(self):
data_frame = search(f"select objid from sim_objs where objType={self.ObjType}")
num = data_frame.size + 1
if isinstance(self, SimHost):
name = "SHO%d" % num
elif isinstance(self, SimRouter):
name = "SRO%d" % num
elif isinstance(self, SimSwitch):
name = "SWI%d" % num
else:
name = "SHUB%d" % num
return name
def create_img(self):
"""
创建图片
:return:
"""
if self.ObjType == 1:
self.img = self.host_img
self.img_tm = self.host_img_tm
elif self.ObjType == 2:
self.img = self.router_img
self.img_tm = self.router_img_tm
elif self.ObjType == 3:
self.img = self.switch_img
self.img_tm = self.switch_img_tm
else:
self.img = self.hub_img
self.img_tm = self.hub_img_tm
self.canvas.delete("L")
id = self.canvas.create_image(self.ObjX - 30, self.ObjY - 30,
image=self.img if self.ConfigCorrect == 1 else self.img_tm, anchor="nw",
tags=self.ObjID)
self.canvas.dtag("L", "L")
self.canvas.create_text(self.ObjX - 20, self.ObjY - 60, text=self.ObjLabel, font=("", 16, "bold"),
fill="#9b78eb", tags=self.ObjID + "text", anchor="nw")
if self.ObjType == 1:
self.canvas.create_text(self.ObjX - 45, self.ObjY + 15, text=self.interface[0]["ip"]if len(self.interface) > 0 else "", font=("", 16, "bold"),
fill="#9b78eb", tags=self.ObjID + "text", anchor="nw")
self.canvas.create_text(self.ObjX - 45, self.ObjY + 35, text=self.interface[0]["mac"]if len(self.interface) > 0 else "", font=("", 16, "bold"),
fill="#9b78eb", tags=self.ObjID + "text", anchor="nw")
self.canvas.create_text(self.ObjX - 45, self.ObjY + 55, text=self.interface[0]["addr"]if len(self.interface) > 0 else "", font=("", 16, "bold"),
fill="#9b78eb", tags=self.ObjID + "text", anchor="nw")
self.canvas.tag_raise(id)
def set_default_config(self):
sql = f"select * from conn_config where node_id='{self.ObjID}'"
conn_data = search(sql)
for index, conn in conn_data.iterrows():
self.interface[int(conn["node_ifs"]) - 1] = {"ip": conn["ip"],
"mac": conn["mac"],
"conn_port": conn["conn_port"],
"addr": conn["addr"]}
def get_config(self):
sql = f"select * from conn_config where node_id='{self.ObjID}'"
conn_data = search(sql)
return conn_data
def transfer_animate(self, status, packet, packet_size, error_message=None):
if status:
text = f"消息大小: {packet_size}\n" \
f"消息内容: {packet}"
self.canvas.create_rectangle(self.ObjX + 30, self.ObjY - 30, self.ObjX + 160, self.ObjY + 20,
outline="#92d050",
width=3, fill="#92d050", tags=self.ObjID + "packetData")
self.canvas.create_text(self.ObjX + 35, self.ObjY - 25, text=text, anchor="nw",
font=('', 10), tags=self.ObjID + "packetData") # 显示文字
self.canvas.update()
sleep(2)
self.canvas.delete(self.ObjID + "packetData") # 删除展示的数据包内容
else:
text = f"传输失败\n" if error_message is None else error_message
self.canvas.create_rectangle(self.ObjX + 30, self.ObjY - 30, self.ObjX + 160, self.ObjY, outline="red",
width=3, fill="red", tags=self.ObjID + "packetData")
self.canvas.create_text(self.ObjX + 35, self.ObjY - 25, text=text, anchor="nw",
font=('', 10), tags=self.ObjID + "packetData") # 显示文字
self.canvas.update()
sleep(2)
self.canvas.delete(self.ObjID + "packetData") # 删除展示的数据包内容
def create_detail_button(self):
frist_x = self.ObjX # 获取frist_x
frist_y = self.ObjY # 获取frist_y
tag_id = self.ObjID + "detail_button"
self.canvas.create_rectangle(frist_x + 10, frist_y - 25, frist_x + 40, frist_y - 15, fill="#f0a732",
outline="#47b2ff",width=2, tags=tag_id)
def __str__(self):
str = ""
config = self.get_config()
for index, data in config.iterrows():
str += f"【接口{data['node_ifs']}\n"
str += f"IP: {data['ip']}\n"
str += f"MAC: {data['mac']}\n"
return str
class SimPacket():
# todo: 数据包类
"""
数据包类
"""
def __init__(self, source_ip, source_mac, destination_ip, destination_mac, message, label, size, sendObj, receiveObj):
"""
:param source_mac: 源主机mac地址
:param source_ip: 源主机ip地址
:param destination_mac: 目的主机mac地址
:param destination_ip: 目的主机ip地址
:param message: 数据
"""
self.source_mac = source_mac
self.source_ip = source_ip
self.sendObj = sendObj
self.receiveObj = receiveObj
self.destination_mac = destination_mac
self.destination_ip = destination_ip
self.message = message
self.label = label
self.size = size
self.up_jump = None # 上一跳连接对象
self.objs = set()
self.img = None
self.id = str(uuid4())
self.process_img()
def process_img(self):
img = Image.open(sys.path[0] + "/../datas/images/packet.png").resize((30, 30))
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("arial.ttf", size=16)
text_width, text_height = draw.textsize(str(self.label), font=font)
# 计算文本在右上角的位置
x = img.width - text_width - 10 # 右上角距离右边缘10像素
y = 10 # 距离上边缘10像素
# 绘制文本
draw.text((x, y), str(self.label), font=font, fill=(255, 0, 0)) # 红色字体
self.img = ImageTk.PhotoImage(img)
def move(self, id, cv, target_x, target_y, duration):
start_x, start_y = cv.coords(id)
distance_x = target_x - start_x
distance_y = target_y - start_y
steps = duration // 10 # 以10毫秒为间隔进行移动
step_x = distance_x / steps
step_y = distance_y / steps
self._move_step(id, cv, start_x, start_y, target_x, target_y, step_x, step_y, steps)
def _move_step(self,id, cv, start_x, start_y, target_x, target_y, step_x, step_y, steps):
if pause_event.is_set():
new_x = start_x + step_x
new_y = start_y + step_y
sleep(2)
self._move_step(id, cv, new_x, new_y, target_x, target_y, step_x, step_y, steps)
if steps > 0:
new_x = start_x + step_x
new_y = start_y + step_y
cv.coords(id, new_x, new_y)
cv.update() # 更新画布显示
sleep(0.01) # 添加延迟以控制动画速度
self._move_step(id, cv, new_x, new_y, target_x, target_y, step_x, step_y, steps - 1)
else:
cv.coords(id, target_x, target_y)
cv.delete(id)
def transfer_packet(self, cv: Canvas, nodex_tag: SimBase, nodey_tag: SimBase):
self.objs.add(nodex_tag)
self.objs.add(nodey_tag)
cv.create_image(nodex_tag.ObjX - 15, nodex_tag.ObjY - 15, image=self.img, anchor="nw", tags=self.id)
self.move(self.id, cv, nodey_tag.ObjX - 15, nodey_tag.ObjY - 15, 500)
class AllSimConnect():
# todo: 连接类
def __init__(self, canvas, nodex: SimBase, nodex_ifs, nodey: SimBase, nodey_ifs, config=None):
"""
连接对象
:param nodex: 节点
:param nodex_ifs: 节点接口
:param nodey: 节点
:param nodey_ifs: 节点接口
"""
self.canvas = canvas
self.ConfigCorrect = 0 if config is None else config
self.NobjS = nodex
self.NobjE = nodey
self.IfsS = nodex_ifs
self.IfsE = nodey_ifs
self.width = False if self.ConfigCorrect == 0 else True # 线的粗细
def transfer(self, source_node, packet: SimPacket):
"""
传输数据
:param packet: 数据包
:return:
"""
if source_node == self.NobjS:
packet.transfer_packet(self.canvas, self.NobjS, self.NobjE)
self.NobjE.receive(packet)
else:
packet.transfer_packet(self.canvas, self.NobjE, self.NobjS)
self.NobjS.receive(packet)
def draw_line(self):
if self.width:
line = self.canvas.create_line(self.NobjS.ObjX, self.NobjS.ObjY, self.NobjE.ObjX, self.NobjE.ObjY,
width=2, fill="#c372f0", tags=self.NobjS.ObjID + self.NobjE.ObjID + "line")
else:
line = self.canvas.create_line(self.NobjS.ObjX, self.NobjS.ObjY, self.NobjE.ObjX, self.NobjE.ObjY,
width=2, dash=(250, 4), fill="#c372f0",
tags=self.NobjS.ObjID + self.NobjE.ObjID + "line")
self.canvas.tag_lower(line, 2)
class SimHost(SimBase):
# todo: 主机类
"""
主机类
"""
def __init__(self, canvas, x, y, id=None, config=None, label=None):
self.ObjID = str(uuid4()) if id is None else id
super().__init__(canvas, x, y, self.ObjID, config, label)
self.ObjType = 1
self.ObjLabel = label if label is not None else self.set_default_name()
self.interface = [{}]
self.connections = [None]
self.set_default_config()
def packet_ok(self, receiveObj, label, size):
count = split_appdata(int(size))
for i in range(2, count + 1):
pack = SimPacket(self.interface[0]["ip"], self.interface[0]["mac"],
receiveObj.interface[0]["ip"], receiveObj.interface[0]["mac"], label, i, size, self,
receiveObj)
threading.Timer(1 * (i - 1), function=self.send, args=(pack,), ).start()
def create_packet(self, receiveObj, label, size):
"""
创建数据包
:param receiveObj: 目的主机对象
:param message: 消息
:return:
"""
def send(message):
print(message)
pack = SimPacket(self.interface[0]["ip"], self.interface[0]["mac"],
receiveObj.interface[0]["ip"], receiveObj.interface[0]["mac"], message, 1, size, self,
receiveObj)
self.send(pack)
message = """发送主机:{}\n\nIP地址{}\n\nMac地址{}\n\n发送数据包大小:{}\n\n已发送数据数量:{}\n\n需要发送的数据包总数:{}"""
self.packet_window = PacketWindow(self.canvas, packet={"packet": True,
"size": int(size),
"sendObj": self,
"receiveObj": receiveObj,
"tag": label,
"send": send,
"mode": [{"app": True},{"trans": True},{"ip": True},{"mac": True}]})
self.packet_window.title("{} 封包".format(self.ObjLabel))
def send(self, packet):
"""
发送数据包
:param packet:
:return:
"""
connection: AllSimConnect = self.connections[0]
print(f"数据包从 {self.ObjLabel} 发出")
packet.up_jump = connection
connection.transfer(self, packet)
def receive(self, packet: SimPacket):
"""
接收数据
:param packet: 数据包
:return:
"""
data = ""
def receive(message):
data = message
self.is_un_packet = True
packet.sendObj.packet_ok(self, data, int(packet.size))
if not self.is_un_packet:
PacketWindow(self.canvas, {"packet": False,
"size": None,
"sendObj": packet.sendObj,
"receiveObj": self,
"tag": packet.message,
"send": receive,
"mode": [{"app": True},{"trans": True},{"ip": True},{"mac": True}]}, packet_step=["app", "trans", "ip", "mac"][::-1])
size = int(packet.size)
message = """接收主机:{}\n\nIP地址{}\n\nMac地址{}\n\n发送数据包大小:{}\n\n已接收数据数量:{}\n\n需要发送的数据包总数:{}"""
self.canvas.show_bottom_message(self, message=message.format(self.ObjLabel, self.interface[0]["ip"],
self.interface[0]["mac"],
size, packet.label, split_appdata(size)))
if split_appdata(size) == packet.label:
if packet.destination_ip == self.interface[0]["ip"]:
self.transfer_animate(True, packet.message, size)
self.canvas.message.show_message(f"{self.ObjLabel}接收到数据:{data}")
else:
self.transfer_animate(False, data, size)
self.canvas.trans_over(packet.objs)
def __str__(self):
str = ""
config = self.get_config()
for index, data in config.iterrows():
str += f"【接口{data['node_ifs']}\n"
str += f"AppAddr: /Root\n"
str += f"PORT: {data['conn_port']}\n"
str += f"IP: {data['ip']}\n"
str += f"MAC: {data['mac']}\n"
return str
class SimRouter(SimBase):
# todo: 路由类
"""
路由类
"""
def __init__(self, canvas, x, y, id=None, config=None, label=None, *args):
self.ObjID = str(uuid4()) if id is None else id
super().__init__(canvas, x, y, self.ObjID, config, label)
self.ObjType = 2
self.ObjLabel = label if label is not None else self.set_default_name()
self.router_table = {}
self.set_default_router_table()
def set_default_router_table(self):
"""
将数据库中的路由表信息提取
:return:
"""
sql = f"select * from router_table where obj_id='{self.ObjID}'"
router_tables = search(sql)
for index, router_table in router_tables.iterrows():
if router_table["node_ifs"] in self.router_table:
self.router_table[router_table["node_ifs"]].append(router_table["segment"])
else:
self.router_table[router_table["node_ifs"]] = [router_table["segment"]]
def check_destination_ip(self, destination_ip, network):
"""
检查目标ip是否属于网段范围内
:param destination_ip: 目标ip
:param network: 网段
:return:10.2.3.0/24
"""
ip = ipaddress.ip_address(destination_ip)
network = ipaddress.ip_network(network)
if ip in network:
return True
if network == "0.0.0.0/24": # 如果网段为 0.0.0.0/24 则为默认路由
return True
def transmit(self, packet: SimPacket):
"""
转发数据包
:return:
"""
def transfer():
flag = False
next_hop_ifs = None
for conn in self.connections:
if isinstance(conn, AllSimConnect):
if conn.ConfigCorrect == 0:
continue
if conn == packet.up_jump:
continue
ifs = self.connections.index(conn) + 1
if self.router_table.get(ifs) is None:
continue
for network in self.router_table.get(ifs):
if self.check_destination_ip(packet.destination_ip, network):
flag = True
next_hop_ifs = ifs
if flag:
conn = self.connections[next_hop_ifs - 1]
packet.up_jump = conn
conn.transfer(self, packet)
else:
for conn in self.connections:
if isinstance(conn, AllSimConnect):
if conn == packet.up_jump:
continue
if conn.NobjS != self:
if conn.NobjE.ObjType == 1:
conn.transfer(self, packet)
break
error_message = "路由寻址失败"
self.transfer_animate(False, packet, error_message)
def receive(message):
packet.message = message
self.is_packet = True
transfer()
if not self.is_packet:
PacketWindow(self.canvas, {"packet": True,
"size": None,
"sendObj": packet.sendObj,
"receiveObj": packet.receiveObj,
"tag": packet.message,
"send": receive,
"mode": [{"app": False}, {"trans": False}, {"ip": True}, {"mac": True}]},
packet_step=["ip", "mac"])
else:
transfer()
def receive(self, packet):
"""
接收数据
:param packet: 数据包
:return:
"""
def receive(message):
print(message)
self.is_un_packet = True
packet.message = message
sleep(1.5)
self.transmit(packet)
if not self.is_un_packet:
PacketWindow(self.canvas, {"packet": False,
"size": None,
"sendObj": packet.sendObj,
"receiveObj": packet.receiveObj,
"tag": packet.message,
"send": receive,
"mode": [{"app": False}, {"trans": False}, {"ip": True}, {"mac": True}]},
packet_step=["ip", "mac"][::-1])
else:
self.transmit(packet)
class SimSwitch(SimBase):
# todo: 交换机类
"""
交换机类
"""
def __init__(self, canvas, x, y, id=None, config=None, label=None, *args):
self.ObjID = str(uuid4()) if id is None else id
super().__init__(canvas, x, y, self.ObjID, config, label)
self.ObjType = 3
self.ObjLabel = label if label is not None else self.set_default_name()
self.mac_table = {}
self.set_default_mac_table()
def set_default_mac_table(self):
"""
将数据库中的路由表信息提取
:return:
"""
sql = f"select * from mac_table where obj_id='{self.ObjID}'"
router_tables = search(sql)
for index, router_table in router_tables.iterrows():
if router_table["node_ifs"] in self.mac_table:
self.mac_table[router_table["node_ifs"]].append(router_table["mac"])
else:
self.mac_table[router_table["node_ifs"]] = [router_table["mac"]]
def transmit(self, packet: SimPacket):
"""
转发数据包
:return:
"""
flag = False
next_hub_ifs = None
for conn in self.connections:
if isinstance(conn, AllSimConnect):
if conn.ConfigCorrect == 0:
continue
ifs = self.connections.index(conn) + 1
if packet.destination_mac in self.mac_table.get(ifs, []):
flag = True
next_hub_ifs = ifs
if flag:
conn = self.connections[next_hub_ifs - 1]
packet.up_jump = conn
conn.transfer(self, packet)
return
for conn in self.connections: # 将数据包往所有接口进行转发
if isinstance(conn, AllSimConnect):
if conn == packet.up_jump:
continue
if conn.ConfigCorrect == 0:
continue
new_packet = SimPacket(packet.source_ip,
packet.source_mac,
packet.destination_ip,
packet.destination_mac,
packet.message)
new_packet.up_jump = conn
threading.Thread(target=conn.transfer, args=(self, new_packet)).start()
def receive(self, packet: SimPacket):
"""
接收数据
:param packet: 数据包
:return:
"""
print(f"交换机{self.ObjLabel}接受到数据{packet.message}")
self.transmit(packet)
class SimHub(SimBase):
"""
集线器类
"""
def __init__(self, canvas, x, y, id=None, config=None, label=None, *args):
self.ObjID = str(uuid4()) if id is None else id
super().__init__(canvas, x, y, self.ObjID, config, label)
self.ObjType = 4
self.ObjLabel = label if label is not None else self.set_default_name()
def transmit(self, packet: SimPacket):
"""
集线器转发数据包
:return:
"""
for conn in self.connections: # 将数据包往所有接口进行转发
if isinstance(conn, AllSimConnect):
if conn == packet.up_jump:
continue
if conn.ConfigCorrect == 0:
continue
new_packet = SimPacket(packet.source_ip,
packet.source_mac,
packet.destination_ip,
packet.destination_mac,
packet.message)
new_packet.up_jump = conn
threading.Thread(target=conn.transfer, args=(self, new_packet)).start()
def receive(self, packet: SimPacket):
"""
接收数据
:param packet: 数据包
:return:
"""
print(f"集线器-{self.ObjLabel}接受到数据,将进行转发!")
self.transmit(packet)

@ -0,0 +1,268 @@
import ipaddress
import re
import sqlite3
from tkinter import messagebox
import ttkbootstrap as tk
from ttkbootstrap import *
from ttkbootstrap import ttk
import pandas as pd
from SimObjs import SimRouter
def round_rectangle(cv, x1, y1, x2, y2, radius=30, **kwargs):
"""
绘制圆角矩形
:param cv: canvas对象
:param radius: 圆角值
:return:
"""
points = [x1 + radius, y1,
x1 + radius, y1,
x2 - radius, y1,
x2 - radius, y1,
x2, y1,
x2, y1 + radius,
x2, y1 + radius,
x2, y2 - radius,
x2, y2 - radius,
x2, y2,
x2 - radius, y2,
x2 - radius, y2,
x1 + radius, y2,
x1 + radius, y2,
x1, y2,
x1, y2 - radius,
x1, y2 - radius,
x1, y1 + radius,
x1, y1 + radius,
x1, y1]
return cv.create_polygon(points, **kwargs, smooth=True)
def validate_ip_address(ip_address):
"""
匹配ip地址格式是否规范
:param ip_address: IP地址
:return: Boolean
"""
# 定义IP地址的正则表达式模式
pattern_with_subnet = r'^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})$'
pattern_without_subnet = r'^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$'
# 使用re模块进行匹配
match_with_subnet = re.match(pattern_with_subnet, ip_address)
match_without_subnet = re.match(pattern_without_subnet, ip_address)
if match_with_subnet:
# 带有子网掩码的IP地址
# 检查每个组件的取值范围是否在 0-255 之间
for group in match_with_subnet.groups()[:4]:
if not (0 <= int(group) <= 255):
return False
# 检查子网掩码的取值范围是否在 0-32 之间
subnet_mask = int(match_with_subnet.groups()[4])
if not (0 <= subnet_mask <= 32):
return False
return True
elif match_without_subnet:
# 不带子网掩码的IP地址
# 检查每个组件的取值范围是否在 0-255 之间
for group in match_without_subnet.groups():
if not (0 <= int(group) <= 255):
return False
return True
else:
# IP地址格式不正确
return False
class ExportUtil():
def __init__(self, path):
self.conn = sqlite3.connect('./network.db')
self.path = path
def get_table_names(self):
cursor = self.conn.cursor()
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';") # 如果你使用SQLite数据库
tables = cursor.fetchall()
cursor.close()
return [table[0] for table in tables]
def export(self):
tables = self.get_table_names()
with pd.ExcelWriter(self.path, engine='openpyxl') as writer:
for table in tables:
table_name = table
# a. 从数据库中获取表的数据并存储在DataFrame中
query = f"SELECT * FROM {table_name}"
df = pd.read_sql(query, self.conn)
# b. 使用Pandas将数据写入Excel文件的不同sheet中
df.to_excel(writer, sheet_name=table_name, index=False)
def import_data(self):
excel_file = pd.ExcelFile(self.path)
sheet_names = excel_file.sheet_names
print(sheet_names)
cursor = self.conn.cursor()
for sheet_name in sheet_names:
# 4. 使用 Pandas 读取工作表数据
df = pd.read_excel(excel_file, sheet_name=sheet_name)
# 5. 获取工作表的列名
columns = df.columns.tolist()
# 6. 构造插入语句
columns_str = ', '.join(columns)
placeholders = ', '.join(['?' for _ in range(len(columns))])
sql = f"INSERT INTO {sheet_name} ({columns_str}) VALUES ({placeholders})"
# 7. 将数据插入数据库
for index, row in df.iterrows():
# 8. 使用动态生成的 SQL 语句将数据插入数据库
cursor.execute(sql, tuple(row))
self.conn.commit()
class RouterConfigWindow(tk.Toplevel):
def __init__(self, parent, router_obj):
super().__init__(parent)
self.geometry("435x433+350+200")
self.title(f"{router_obj.ObjLabel}路由表配置")
self.router_obj = router_obj
self.interface_entries = []
self.router_table = {}
self.create_interface_inputs()
self.create_router_table()
def create_interface_inputs(self):
label_text = ["接口1", "接口2", "接口3", "接口4"]
for i in range(4):
label = tk.Label(self, text=label_text[i], font=("黑体", 16))
label.grid(row=i, column=0, padx=10, pady=5, sticky="w")
entry = tk.Entry(self, width=20, font=("黑体", 16),)
entry.grid(row=i, column=1, padx=10, pady=5, sticky="w")
self.interface_entries.append(entry)
button = tk.Button(self, text="添加", font=("黑体", 16), command=lambda index=i: self.add_router_entry(index))
button.grid(row=i, column=2, padx=10, pady=5)
lab = LabelFrame(self, text="示例")
lab.grid(row=4, column=0, columnspan=3, sticky=W, padx=20)
Label(lab, text="10.1.2.0/24 或者 10.1.2.12" if self.router_obj.ObjType == 2 else "MAC11", font=("黑体", 16)).pack()
def create_router_table(self):
def on_right_click(event):
row = self.router_treeview.identify_row(event.y) # 获取鼠标位置的行索引
if row:
self.router_treeview.selection_set(row) # 选中该行
delete_menu.post(event.x_root, event.y_root) # 在鼠标位置弹出删除菜单
def delete_row():
selected_items = self.router_treeview.selection() # 获取选中的行
for item in selected_items:
ifs, network = int(self.router_treeview.item(item)["values"][0][-1:]), self.router_treeview.item(item)["values"][1]
self.router_obj.delete_config(ifs, network)
self.router_treeview.delete(item)
self.router_table_frame = tk.Frame(self)
self.router_table_frame.grid(row=5, column=0, columnspan=3, padx=10, pady=5)
style = ttk.Style()
style.configure("Custom.Treeview.Heading", font=("宋体", 15))
style.configure("Custom.Treeview", rowheight=30, font=("宋体", 15))
self.router_treeview = ttk.Treeview(self.router_table_frame, style="Custom.Treeview", columns=("Interface", "Route"), show="headings")
self.router_treeview.heading("Interface", text="接口")
self.router_treeview.heading("Route", text="网段")
self.router_treeview.pack(side="left", fill="both")
scrollbar = ttk.Scrollbar(self.router_table_frame, orient="vertical", command=self.router_treeview.yview)
scrollbar.pack(side="right", fill="y")
self.router_treeview.configure(yscrollcommand=scrollbar.set)
self.router_table = self.router_obj.router_table
self.router_treeview.bind("<Button-3>", on_right_click)
# 创建删除菜单
delete_menu = tk.Menu(self.master, tearoff=False)
delete_menu.add_command(label="删除", command=delete_row)
self.update_router_table()
def add_router_entry(self, index):
entry_text = self.interface_entries[index].get()
try:
ipaddress.ip_network(entry_text)
if isinstance(self.router_obj, SimRouter):
if not validate_ip_address(entry_text):
messagebox.showerror("注意", message="添加的网段信息格式不合格")
self.interface_entries[index].delete(0, tk.END)
self.focus_set()
return
if entry_text:
if index + 1 in self.router_table:
self.router_table[index + 1].append(entry_text)
else:
self.router_table[index + 1] = [entry_text]
self.interface_entries[index].delete(0, tk.END)
self.router_obj.add_config(entry_text, index + 1)
self.update_router_table()
self.master.message.show_message(f"{self.router_obj.ObjLabel}添加配置{entry_text}成功!")
except:
messagebox.showerror("注意", message="网段格式错误!网段示例如下:\n10.1.2.0/24\n10.1.2.12")
return
def update_router_table(self):
self.router_treeview.delete(*self.router_treeview.get_children())
for i, entrys in self.router_table.items():
for entry in entrys:
self.router_treeview.insert("", "end", values=(f"接口{i}", entry))
class SwitchConfigWindow(RouterConfigWindow):
def __init__(self, parent, router_obj):
super().__init__(parent, router_obj)
self.geometry("435x433+350+200")
self.title(f"{router_obj.ObjLabel}交换表配置")
self.router_obj = router_obj
self.interface_entries = []
self.router_table = {}
self.create_interface_inputs()
self.create_router_table()
def create_router_table(self):
def on_right_click(event):
row = self.router_treeview.identify_row(event.y) # 获取鼠标位置的行索引
if row:
self.router_treeview.selection_set(row) # 选中该行
delete_menu.post(event.x_root, event.y_root) # 在鼠标位置弹出删除菜单
def delete_row():
selected_items = self.router_treeview.selection() # 获取选中的行
for item in selected_items:
ifs, network = int(self.router_treeview.item(item)["values"][0][-1:]), self.router_treeview.item(item)["values"][1]
self.router_obj.delete_config(ifs, network)
self.router_treeview.delete(item)
self.router_table_frame = tk.Frame(self)
self.router_table_frame.grid(row=5, column=0, columnspan=3, padx=10, pady=5)
self.router_treeview = ttk.Treeview(self.router_table_frame, columns=("Interface", "Route"), show="headings")
self.router_treeview.heading("Interface", text="接口")
self.router_treeview.heading("Route", text="mac")
self.router_treeview.pack(side="left", fill="both")
scrollbar = ttk.Scrollbar(self.router_table_frame, orient="vertical", command=self.router_treeview.yview)
scrollbar.pack(side="right", fill="y")
self.router_treeview.configure(yscrollcommand=scrollbar.set)
self.router_table = self.router_obj.mac_table
self.router_treeview.bind("<Button-3>", on_right_click)
# 创建删除菜单
delete_menu = tk.Menu(self.master, tearoff=False)
delete_menu.add_command(label="删除", command=delete_row)
self.update_router_table()
def add_router_entry(self, index):
entry_text = self.interface_entries[index].get()
if isinstance(self.router_obj, SimRouter):
if not validate_ip_address(entry_text):
messagebox.showerror("注意", message="添加的网段信息格式不合格")
self.interface_entries[index].delete(0, tk.END)
self.focus_set()
return
if entry_text:
if index + 1 in self.router_table:
self.router_table[index + 1].append(entry_text)
else:
self.router_table[index + 1] = [entry_text]
self.interface_entries[index].delete(0, tk.END)
self.router_obj.add_config(entry_text, index + 1)
self.master.message.show_message(f"{self.router_obj.ObjLabel}添加配置{entry_text}成功!")
self.update_router_table()

Binary file not shown.

@ -0,0 +1,104 @@
import sqlite3
import sys
import pandas as pd
from pandas import DataFrame
conn = sqlite3.connect(sys.path[0]+"/network.db")
def execute_sql(sql):
"""
执行sql语句
:param sql:
:return:
"""
cursor = conn.cursor()
cursor.execute(sql)
conn.commit()
def search(sql) -> DataFrame:
return pd.read_sql(sql, conn)
def delete_obj(obj_id):
cursor = conn.cursor()
delete_obj_sql = f"delete from sim_objs where ObjID='{obj_id}'"
cursor.execute(delete_obj_sql)
delete_conn_sql = f"delete from sim_conn where conn_id in (select conn_id from conn_config where node_id='{obj_id}')"
cursor.execute(delete_conn_sql)
conn.commit()
def truncate_db():
init_database()
def init_database():
cursor = conn.cursor()
cursor.execute("""
DROP TABLE IF EXISTS `conn_config`;
""")
cursor.execute("""
CREATE TABLE `conn_config` (
`conn_id` varchar(55) NULL DEFAULT NULL,
`node_id` varchar(55) NULL DEFAULT NULL,
`node_ifs` int(0) NULL DEFAULT NULL,
`ip` varchar(55) NULL DEFAULT NULL,
`mac` varchar(128) NULL DEFAULT NULL,
`conn_port` varchar(32) NULL DEFAULT NULL,
`addr` varchar(255) NULL DEFAULT NULL,
CONSTRAINT `conn_config_sim_conn_conn_id_fk` FOREIGN KEY (`conn_id`) REFERENCES `sim_conn` (`conn_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ;
""")
cursor.execute("""
DROP TABLE IF EXISTS `mac_table`;
""")
cursor.execute("""
CREATE TABLE `mac_table` (
`obj_id` varchar(55) NULL DEFAULT NULL,
`node_ifs` int(0) NULL DEFAULT NULL,
`mac` varchar(55) NULL DEFAULT NULL,
CONSTRAINT `mac_table_sim_objs_ObjID_fk` FOREIGN KEY (`obj_id`) REFERENCES `sim_objs` (`ObjID`) ON DELETE CASCADE ON UPDATE CASCADE
) ;
""")
cursor.execute("""
DROP TABLE IF EXISTS `router_table`;
""")
cursor.execute("""
CREATE TABLE `router_table` (
`obj_id` varchar(55) NULL DEFAULT NULL,
`node_ifs` int(0) NULL DEFAULT NULL,
`segment` varchar(55) NULL DEFAULT NULL,
CONSTRAINT `router_table_sim_objs_ObjID_fk` FOREIGN KEY (`obj_id`) REFERENCES `sim_objs` (`ObjID`) ON DELETE CASCADE ON UPDATE CASCADE
) ;
""")
cursor.execute("""
DROP TABLE IF EXISTS `sim_conn`;
""")
cursor.execute("""
CREATE TABLE `sim_conn` (
`conn_id` varchar(255) NOT NULL ,
`ConfigCorrect` int(0) NULL DEFAULT NULL ,
PRIMARY KEY (`conn_id`)
) ;
""")
cursor.execute("""
DROP TABLE IF EXISTS `sim_objs`;
""")
cursor.execute("""
CREATE TABLE `sim_objs` (
`ObjID` varchar(50) NOT NULL,
`ObjType` int(0) NULL DEFAULT NULL,
`ObjLabel` varchar(20) NULL DEFAULT NULL,
`ObjX` int(0) NULL DEFAULT NULL,
`ObjY` int(0) NULL DEFAULT NULL,
`ConfigCorrect` int(0) NULL DEFAULT NULL,
PRIMARY KEY (`ObjID`)
) ;
""")
conn.commit()
if __name__ == '__main__':
init_database()

Binary file not shown.

@ -0,0 +1,438 @@
import time
from SimObjs import *
from tkinter import *
from tkinter import messagebox
from PIL import ImageTk, Image
from AgreementUtil import AgreementUtil
def create_label(canvas: Canvas, x, y, width, height, text, rect_color, font_color, tag):
canvas.create_rectangle(x, y, x + width, y + height, fill=rect_color, tags=tag)
canvas.create_text(x + width / 2, y + height / 2, text=text, fill=font_color, tags=tag)
return tag
class PacketWindow(Toplevel):
def __init__(self, master, packet, packet_step=["app", "trans", "ip", "mac"], *args, **kwargs):
"""
packet{"packet": True, "mode": {"app": True, "trans": True, "ip": True, "mac": True}}
"""
super().__init__(master, *args, **kwargs)
self.master = master
self.width = 300
self.height = 400
self.geometry(f"{self.width}x{self.height}+200+200")
self.attributes("-topmost", True)
self.resizable(width=False, height=False)
self.packet_button_str = {"app": "应用层", "ip": "网络层", "mac": "链路层", "trans": "传输层"}
if not packet["packet"]:
packet["mode"] = packet["mode"][::-1] # True 为封包 False 为解包
self.packet_step = packet_step
self.step = 0
self.packet: dict[str: bool] = packet
self.sendObj: SimHost = packet["sendObj"]
self.receiveObj: SimHost = packet["receiveObj"]
self.packet_option = {"app": {"color": "#ff3b26", "command": self.app_packet if packet["packet"] else self.app_unpack},
"ip": {"color": "#00a2f2", "command": self.ip_packet if packet["packet"] else self.ip_unpack},
"mac": {"color": "#46707a", "command": self.mac_packet if packet["packet"] else self.mac_unpack},
"trans": {"color": "#710a00", "command": self.trans_packet if packet["packet"] else self.trans_unpack}}
self.canvas = Canvas(self, width=self.width, height=self.height)
self.canvas.place(x=0, y=0, anchor='nw')
self.packet_height, self.packet_init_width = 25, 100
self.background_img = ImageTk.PhotoImage(Image.open("../datas/images/背景@2x.png").resize((self.width, self.height)))
self.canvas.create_image(0, 0, image=self.background_img, anchor=NW)
# self.packet_rect = create_label(self.canvas, int(self.width / 2) - self.packet_init_width / 2, 10, width=self.packet_init_width, height=self.packet_height, text=self.packet["tag"], rect_color="#dee1e6", font_color="black", tag="packet")
self.step_y = {}
self.message = packet["tag"]
self.create_widget()
def move_to(self, tag, target_x, target_y, speed=10):
# 获取当前位置
current_coords = self.canvas.coords(tag)
if len(current_coords) < 2:
return # 如果没有坐标,就退出函数
current_x, current_y = current_coords[0], current_coords[1]
# 计算移动方向
delta_x = (target_x if target_x else current_x) - current_x
delta_y = (target_y if target_y else current_y) - current_y
# 计算下一步的位置
next_x = current_x + (speed if delta_x > 0 else -speed) if abs(delta_x) > speed else (target_x if target_x else current_x)
next_y = current_y + (speed if delta_y > 0 else -speed) if abs(delta_y) > speed else (target_y if target_y else current_y)
# 移动对象
self.canvas.move(tag, next_x - current_x, next_y - current_y)
# 如果对象还没有到达目标,继续移动
if next_x != (target_x if target_x else current_x) or next_y != (target_y if target_y else current_y):
self.canvas.after(10, lambda: self.move_to(tag, target_x, target_y, speed))
def create_widget(self):
mode_text = "封包" if self.packet["packet"] else "解包"
num, margin_top, button_width, button_height = 1, 30, 120, 40
for data in self.packet["mode"]:
key = list(data.keys())[0]
value = list(data.values())[0]
if value:
Button(self, text=self.packet_button_str[key] + mode_text, command=self.packet_option[key]["command"],
font=("", 16)).place(x=40, y=30 + (margin_top + button_height) * (num - 1),
width=button_width, height=button_height)
# 动画
# self.canvas.create_rectangle(self.width - 80 - 40, 80 + (margin_top + 20 + button_height) * (num - 1),
# self.width - 40, 80 + (margin_top + 20 + button_height) * (num - 1) + 25, fill=self.packet_option[key]["color"])
# self.canvas.create_text(self.width - 40 - 40, 80 + (margin_top + 20 + button_height) * (num - 1) + 12.5,
# text=self.packet_button_str[key], font=("", 16), fill="white")
# self.step_y[key] = 80 + (margin_top + 20 + button_height) * (num - 1)
num += 1
Button(self, text="发送", command=self.send_packet, font=("", 16)).place(x=self.width - 60, y=self.height - 40, anchor=NW)
Button(self, text="取消", command=self.destroy, font=("", 16)).place(x=self.width - 120, y=self.height - 40, anchor=NW)
def send_packet(self):
if self.step != len(self.packet_step):
messagebox.showerror("注意", "尚未完成{}".format("封包" if self.packet["packet"] else "解包"))
return
self.packet["send"](self.message)
self.destroy()
def create_window(self, option):
toplevel = Toplevel(self)
toplevel.title(option["title"])
toplevel.geometry("450x220+300+300")
for entry_option in option["entry"]:
index = option["entry"].index(entry_option)
key = list(entry_option.keys())[0]
value = list(entry_option.values())[0]
Label(toplevel, text=key, font=("", 16)).grid(row=index, column=0, padx=20, pady=10)
if value is None:
continue
Entry(toplevel, textvariable=value, font=("", 16), width=15).grid(row=index, column=1, pady=10)
Button(toplevel, text="提交", command=option["command"], font=("", 16)).place(x=450 - 60, y=220 - 40, anchor=NW)
Button(toplevel, text="取消", command=toplevel.destroy, font=("", 16)).place(x=450 - 120, y=220 - 40, anchor=NW)
toplevel.attributes("-topmost", True)
return toplevel
def app_packet(self):
"""
应用层封包
"""
if self.packet_step[self.step] != "app":
messagebox.showerror("注意", "封包顺序出错!")
return
SourceAppAddr = StringVar()
TargetAppAddr = StringVar()
def packet():
toplevel.destroy()
source_app_addr = SourceAppAddr.get()
target_app_addr = TargetAppAddr.get()
if source_app_addr == self.sendObj.interface[0]["addr"] \
and target_app_addr == self.receiveObj.interface[0]["addr"]:
# 动画
# app_rect = create_label(self.canvas, self.width / 2 + 200, int(self.step_y["app"]), 50, 25, "AH", "#ff3b26", "white", tag="app")
# self.move_to(self.packet_rect, None, int(self.step_y["app"]), speed=1)
# self.move_to(app_rect, self.width / 2 + self.packet_init_width / 2, int(self.step_y["app"]), speed=1)
self.message = target_app_addr + "&" + self.packet["tag"]
self.master.message.show_message("应用层封包成功!数据包如下: \n{}".format(self.message))
self.step += 1
else:
messagebox.showerror("提示", "应用层地址填写有误,请仔细检查!")
toplevel = self.create_window({"title": "应用层封包", "entry": [{"发送主机应用层地址:": SourceAppAddr}, {"接收主机应用层地址:": TargetAppAddr}],
"command": packet})
def app_unpack(self):
"""
应用层解包
"""
if self.packet_step[self.step] != "app":
messagebox.showerror("注意", "解包顺序出错!")
return
TargetAppAddr = StringVar()
def packet():
toplevel.destroy()
target_app_addr = TargetAppAddr.get()
if target_app_addr == self.receiveObj.interface[0]["addr"]:
self.message = self.message.split("&")[1]
self.master.message.show_message("应用层解包成功!数据包如下: \n{}".format(self.message))
self.step += 1
else:
messagebox.showerror("提示", "应用层地址填写有误,请仔细检查!")
toplevel = self.create_window({"title": "应用层解包", "entry": [{"接收主机应用层地址:": TargetAppAddr}],
"command": packet})
def trans_packet(self):
"""
传输层封包
"""
if self.packet_step[self.step] != "trans":
messagebox.showerror("注意", "封包顺序出错!")
return
SentPort = StringVar()
RcptPort = StringVar()
SplitCount = IntVar()
def packet():
sent_port = SentPort.get()
rcpt_port = RcptPort.get()
split_count = SplitCount.get()
count = split_appdata(self.packet["size"])
print(sent_port, self.sendObj.interface[0]["conn_port"])
if sent_port == self.sendObj.interface[0]["conn_port"] \
and rcpt_port == self.receiveObj.interface[0]["conn_port"]\
and split_count == count:
toplevel.destroy()
# 动画
# self.canvas.delete(self.packet_rect)
# self.canvas.delete("app")
# self.packet_rect = create_label(self.canvas, int(self.width / 2) - self.packet_init_width / 2, int(self.step_y["app"]),
# width=self.packet_init_width + 50, height=self.packet_height,
# text="A-" + self.packet["tag"], rect_color="#dee1e6", font_color="black",
# tag="packet")
# trans_rect = create_label(self.canvas, self.width / 2 + 200, int(self.step_y["trans"]), 50, 25, "PH", "#ff3b26",
# "white", tag="trans")
# self.move_to(self.packet_rect, None, int(self.step_y["trans"]), speed=1)
# self.move_to(trans_rect, self.width / 2 + self.packet_init_width / 2 + 50, int(self.step_y["trans"]), speed=1)
self.message = AgreementUtil.create_udp_packet(self.message, int(sent_port), int(rcpt_port))
self.master.message.show_message("传输层封包成功!数据包如下:\n{}".format(str([str(i + 1) + "-" + str(self.message) for i in range(split_count)])))
self.step += 1
else:
messagebox.showerror("提示", "传输层封包信息填写有误,请仔细检查!")
toplevel = self.create_window({"title": "传输层封包", "entry": [{"发送主机端口:": SentPort},
{"接收主机端口:": RcptPort},
{"拆包数量": SplitCount},
{"每个包约2048": None}],
"command": packet})
def trans_unpack(self):
"""
传输层解包
"""
print(self.packet_step)
print(self.step)
if self.packet_step[self.step] != "trans":
messagebox.showerror("注意", "解包顺序出错!")
return
RcptPort = StringVar()
def packet():
rcpt_port = RcptPort.get()
if rcpt_port == self.receiveObj.interface[0]["conn_port"]:
toplevel.destroy()
data = AgreementUtil.parse_udp_packet(self.message)
print(data)
self.message = data[-1]
self.master.message.show_message("传输层解包成功!数据包如下:\n{}".format(self.message))
self.step += 1
else:
messagebox.showerror("提示", "传输层解包信息填写有误,请仔细检查!")
toplevel = self.create_window({"title": "传输层解包", "entry": [{"接收主机端口:": RcptPort}],
"command": packet})
def ip_packet(self):
"""
网络层封包
"""
if self.packet_step[self.step] != "ip":
messagebox.showerror("注意", "封包顺序出错!")
return
SourceIP = StringVar()
TargetIP = StringVar()
def packet():
source_ip = SourceIP.get()
target_ip = TargetIP.get()
if source_ip == self.sendObj.interface[0]["ip"] \
and target_ip == self.receiveObj.interface[0]["ip"]:
toplevel.destroy()
self.message = AgreementUtil.create_ip_packet(self.message, source_ip, target_ip)
self.master.message.show_message("网络层封包成功!数据包如下:\n{}".format(self.message))
self.step += 1
else:
messagebox.showerror("提示", "网络层封包信息填写有误,请仔细检查!")
toplevel = self.create_window({"title": "网络层封包", "entry": [{"发送主机IP": SourceIP},
{"接收主机IP": TargetIP}],
"command": packet})
def ip_unpack(self):
"""
网络层解包
"""
print(self.packet_step)
print(self.step)
if self.packet_step[self.step] != "ip":
messagebox.showerror("注意", "解包顺序出错!")
return
RcptIP = StringVar()
def packet():
rcpt_ip = RcptIP.get()
if rcpt_ip == self.receiveObj.interface[0]["ip"]:
toplevel.destroy()
data = AgreementUtil.parse_ip_packet(self.message)
print(data)
self.message = data[-1]
self.master.message.show_message("网络层解包成功!数据包如下:\n{}".format(self.message))
self.step += 1
else:
messagebox.showerror("提示", "网络层解包信息填写有误,请仔细检查!")
toplevel = self.create_window({"title": "网络层解包", "entry": [{"接收主机IP": RcptIP}],
"command": packet})
def mac_packet(self):
"""
链路层封包
"""
if self.packet_step[self.step] != "mac":
messagebox.showerror("注意", "封包顺序出错!")
return
SentMac = StringVar()
RcptMac = StringVar()
def packet():
sent_mac = SentMac.get()
rcpt_mac = RcptMac.get()
if sent_mac == self.sendObj.interface[0]["mac"] \
and rcpt_mac == self.receiveObj.interface[0]["mac"]:
toplevel.destroy()
self.message = AgreementUtil.create_ethernet_frame(self.message, sent_mac, rcpt_mac)
self.master.message.show_message("链路层封包成功!数据包如下:\n{}".format(self.message))
self.step += 1
else:
messagebox.showerror("提示", "链路层封包信息填写有误,请仔细检查!")
toplevel = self.create_window({"title": "链路层封包", "entry": [{"发送主机MAC": SentMac},
{"接收主机MAC": RcptMac}],
"command": packet})
def mac_unpack(self):
"""
链路层解包
"""
if self.packet_step[self.step] != "mac":
messagebox.showerror("注意", "解包顺序出错!")
return
RcptMac = StringVar()
def packet():
rcpt_mac = RcptMac.get()
if rcpt_mac == self.receiveObj.interface[0]["mac"]:
toplevel.destroy()
data = AgreementUtil.parse_ethernet_frame(self.packet["tag"])
print(data)
self.message = data[-1]
self.master.message.show_message("链路层解包成功!数据包如下:\n{}".format(self.message))
self.step += 1
else:
messagebox.showerror("提示", "链路层解包信息填写有误,请仔细检查!")
toplevel = self.create_window({"title": "链路层解包", "entry": [{"接收主机MAC": RcptMac}],
"command": packet})
class AppData:
def __init__(self, obj_id, id_key, app_pack_id, app_pack_size, app_pack_tag, source_app_addr, target_app_addr, app_packed_string, timestamp, canvas):
self.obj_id = obj_id
self.id_key = id_key
self.app_pack_id = app_pack_id
self.app_pack_size = app_pack_size
self.app_pack_tag = app_pack_tag
self.source_app_addr = source_app_addr
self.target_app_addr = target_app_addr
self.app_packed_string = app_packed_string
self.timestamp = timestamp
def pack(self):
# 为了简化,我们打包成一个字典
return vars(self)
@staticmethod
def unpack(packed_data):
# 解包为AppData对象
return AppData(**packed_data)
class TransData:
def __init__(self, obj_id, id_key, trans_pack_id, trans_seq, trans_tag, app_pack_id, sent_port, rcpt_port, source_app_addr, target_app_addr, trans_packed_string, timestamp):
self.obj_id = obj_id
self.id_key = id_key
self.trans_pack_id = trans_pack_id
self.trans_seq = trans_seq
self.trans_tag = trans_tag
self.app_pack_id = app_pack_id
self.sent_port = sent_port
self.rcpt_port = rcpt_port
self.source_app_addr = source_app_addr
self.target_app_addr = target_app_addr
self.trans_packed_string = trans_packed_string
self.timestamp = timestamp
def pack(self):
return vars(self)
@staticmethod
def unpack(packed_data):
return TransData(**packed_data)
class IPData:
def __init__(self, obj_id, id_key, ip_pack_id, trans_pack_id, source_ip, target_ip, source_app_addr, target_app_addr, ip_packed_string):
self.obj_id = obj_id
self.id_key = id_key
self.ip_pack_id = ip_pack_id
self.trans_pack_id = trans_pack_id
self.source_ip = source_ip
self.target_ip = target_ip
self.source_app_addr = source_app_addr
self.target_app_addr = target_app_addr
self.ip_packed_string = ip_packed_string
def pack(self):
return vars(self)
@staticmethod
def unpack(packed_data):
return IPData(**packed_data)
class MACData:
def __init__(self, obj_id, id_key, mac_pack_id, ip_pack_id, sent_mac, rcpt_mac, source_ip, target_ip, source_app_addr, target_app_addr, mac_packed_string):
self.obj_id = obj_id
self.id_key = id_key
self.mac_pack_id = mac_pack_id
self.ip_pack_id = ip_pack_id
self.sent_mac = sent_mac
self.rcpt_mac = rcpt_mac
self.source_ip = source_ip
self.target_ip = target_ip
self.source_app_addr = source_app_addr
self.target_app_addr = target_app_addr
self.mac_packed_string = mac_packed_string
def pack(self):
return vars(self)
@staticmethod
def unpack(packed_data):
return MACData(**packed_data)
def split_appdata(AppPackSize):
MTU = 2048
return AppPackSize // MTU + (AppPackSize % MTU > 0)
if __name__ == '__main__':
# 假设的最大传输单元MTU
MTU = 2048 # bytes
# 模拟的数据和数据大小
SIMULATED_DATA = "hello"
SIMULATED_SIZE = 2049 # 10 MB
# 创建应用层数据包
app_packet = AppData("123", "123", "app1", SIMULATED_SIZE, "DATA", "192.0.2.1", "198.51.100.1", SIMULATED_DATA, time.time())
packed_app_data = app_packet.pack()
print(packed_app_data)

@ -0,0 +1,9 @@
import random
def random_mac():
# 生成六组两位的十六进制数
return ":".join(["%02x" % random.randint(0, 255) for _ in range(6)])
# 生成MAC地址
mac_address = random_mac()
print(mac_address)

@ -0,0 +1,55 @@
packet_count = split_appdata(int(size))
self.canvas.message.show_message("传输层拆包成功!数量:{}".format(packet_count))
for i in range(1, packet_count + 1):
trans_data = TransData(
obj_id=self.ObjID,
id_key=app_data.id_key,
trans_pack_id=str(i),
trans_seq=i,
trans_tag=label,
app_pack_id=app_data.app_pack_id,
sent_port=int(self.interface[0]["conn_port"].split(".")[0]),
rcpt_port=80,
source_app_addr=self.interface[0]['ip'],
target_app_addr=ip,
trans_packed_string=app_data.pack(),
timestamp=int(time.time())
)
self.canvas.message.show_message("传输层数据包{}{}".format(i, trans_data.pack()))
ip_data = IPData(
obj_id=self.ObjID,
id_key="1001",
ip_pack_id="1001",
trans_pack_id=str(i),
source_ip=self.interface[0]["ip"],
target_ip=ip,
source_app_addr=self.interface[0]["ip"],
target_app_addr=ip,
ip_packed_string=trans_data.pack()
)
self.canvas.message.show_message("网络层数据包:{}".format(trans_data.pack()))
mac_data = MACData(
obj_id=self.ObjID,
id_key=app_data.id_key,
mac_pack_id="1001",
ip_pack_id=str(i),
sent_mac=self.interface[0]["mac"],
rcpt_mac=mac,
source_ip=self.interface[0]["ip"],
target_ip=ip,
source_app_addr=self.interface[0]["ip"],
target_app_addr=ip,
mac_packed_string=ip_data.pack()
)
self.canvas.message.show_message("链路层数据包:{}".format(mac_data.pack()))
self.canvas.show_top_message(self, message=message.format(self.ObjLabel, self.interface[0]["ip"], self.interface[0]["mac"],
size, i, packet_count))
packet = SimPacket(self.interface[0]["ip"], self.interface[0]["mac"], ip, mac, mac_data.pack())
thread = threading.Timer(i, function=self.send, args=(packet,))
thread.start()
tk.Button(toplevel, text='开启模拟', font=('黑体', 16), height=1, command=split_packet).grid(row=5, column=0, sticky='e',
pady=10)
tk.Button(toplevel, text='取消', font=('黑体', 16), height=1, command=toplevel.destroy).grid(row=5, column=1,
sticky='e', pady=10)

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

Loading…
Cancel
Save