Как использовать graphviz нарисовать диаграмму инкапсуляции данных TCP/IP?
Я пытаюсь использовать Graphviz, чтобы нарисовать диаграмму инкапсуляции данных TCP/IP в классической книге Стивенса по TCP/IP.
Диаграмма кажется не стандартной компьютерной графикой. Мои вопросы:
- как выровнять вправо?
- Как отметить размер ниже каждой записи (т.е. 14 в заголовке IP, 20 в TCP)?
- как нарисовать край как
|<----------- 46 to 1500 bytes ---------->|
и положить его ниже какого-то узла?
Может ли графвиз нарисовать это? Если так, то как? Заранее спасибо.
1 ответ
- Для выравнивания я использовал прямые края (
splines=false
) и указание того, из какого угла узла они исходят и в какой угол другого узла они входят ( компасные точки ). - Для создания надписей под словами я использовал HTML-метку с двухстрочной таблицей, во второй строке сделал невидимыми нижние границы и границы с левой и правой сторон, установив атрибут
sides="T"
(T
означает верхнюю границу). - Для рисования края, как
|<----------- 46 to 1500 bytes ---------->|
, я использовал уменьшение ширины узла (width=.01
) и невидимые узлы и ребра, их можно найти в скрипте ниже по атрибутуstyle=invis
. Вот небольшой пример с окрашенными в красный цвет элементами, которые не видны на финальном изображении:
Graphviz может его нарисовать (см. пример ниже), но, как ответили в комментариях выше, быстрее будет использовать графический редактор.
Скрипт:
digraph TCP_IP_diagram {
label=<<FONT><B>Figure 1.7 </B> Encapsulation of data as it goes down the protocol stack.</FONT>>
nodesep=0
ranksep=.1
splines=false
edge[style=dashed]
node[shape=box height=.6]
// NODES ------------------------------------
table_0 [margin=0 shape=none label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD PORT="f0" HEIGHT="40" FIXEDSIZE="TRUE">user data</TD></TR>
</TABLE>>]
inv_0 [shape=point style=invis]
table_1 [margin=0 shape=none label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR>
<TD PORT="f0">Appl<BR/>header</TD>
<TD PORT="f1">user data</TD>
</TR>
</TABLE>>]
inv_00 [shape=point style=invis]
table_2 [margin=0 shape=none label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR>
<TD PORT="f0">TCP<BR/>header</TD>
<TD PORT="f1"> application data</TD>
</TR>
</TABLE>>]
{
rank=same;
"TCP segment" [shape=plaintext]
inv_1 [shape=point height=.01]
inv_2 [shape=point height=.01]
}
table_3 [margin=0 shape=none label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR>
<TD PORT="f0">IP<BR/>header</TD>
<TD>TCP<BR/>header</TD>
<TD PORT="f1"> application data</TD>
</TR>
</TABLE>>]
{
rank=same;
"IP datagram" [shape=plaintext]
inv_3 [shape=point height=.01]
inv_4 [shape=point height=.01]
}
table_4 [margin=0 shape=none label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR>
<TD PORT="f0">Ethernet<BR/>header</TD>
<TD>IP<BR/>header</TD>
<TD>TCP<BR/>header</TD>
<TD> application data</TD>
<TD PORT="f1">Ethernet<BR/>trailer</TD>
</TR>
<TR>
<TD SIDES="T">14</TD>
<TD SIDES="T">20</TD>
<TD SIDES="T">20</TD>
<TD SIDES="T"></TD>
<TD SIDES="T">4</TD>
</TR>
</TABLE>>]
{
rank=same;
"Ethernet frame" [shape=plaintext]
inv_5 [shape=box height=.4 width=.01 label=""]
inv_6 [shape=box height=.4 width=.01 label=""]
}
{
rank=same;
"46 to 1500 bytes" [shape=plaintext]
inv_7 [shape=box height=.4 width=.01 label=""]
inv_8 [shape=box height=.4 width=.01 label=""]
}
table_5 [margin=0 shape=none label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BORDER="4" PORT="f0" SIDES="T">Ethernet</TD></TR>
</TABLE>>]
morespace [style=invis shape=plain]
// EDGES ------------------------------------
table_0:f0:se -> table_1:f1:ne
table_0:f0:sw -> table_1:f1:nw
table_0 -> inv_0 [style=invis]
inv_0 -> table_1 [style=invis]
table_1:f0:sw -> table_2:f0:ne
table_1:f1:se -> table_2:f1:ne
table_1 -> inv_00 [style=invis]
inv_00 -> table_2 [style=invis]
table_2 -> "TCP segment" [style=invis]
table_2:f0:sw -> inv_1 [arrowhead=none]
table_2:f1:se -> inv_2 [arrowhead=none]
inv_1 -> table_3:f0:ne
inv_2 -> table_3:f1:ne
"TCP segment" -> inv_1 [weight=0 style=solid]
"TCP segment" -> inv_2 [weight=0 style=solid]
table_3 -> "IP datagram" [style=invis]
table_3:f0:sw -> inv_3 [arrowhead=none]
table_3:f1:se -> inv_4 [arrowhead=none]
"IP datagram" -> inv_3 [weight=0 style=solid]
"IP datagram" -> inv_4 [weight=0 style=solid]
inv_3 -> table_4:f0:ne [style=dashed]
inv_4 -> table_4:f1:nw
table_4 -> "Ethernet frame" [style=invis]
table_4:f0:sw -> inv_5 [style=invis]
table_4:f1:se -> inv_6 [style=invis]
"Ethernet frame" -> inv_5 [weight=0 style=solid]
"Ethernet frame" -> inv_6 [weight=0 style=solid]
"Ethernet frame" -> "46 to 1500 bytes" [style=invis]
table_4:f0:se -> inv_7 [style=invis]
table_4:f1:sw -> inv_8 [style=invis]
"46 to 1500 bytes" -> inv_7 [weight=0 style=solid]
"46 to 1500 bytes" -> inv_8 [weight=0 style=solid]
"46 to 1500 bytes" -> morespace [style=invis]
{
edge [minlen=2]
"application" -> "TCP" -> "IP" -> "Ethernet\ndriver"
}
"Ethernet\ndriver" -> table_5:f0 [style=solid arrowhead=none]
// OTHER RANKS ------------------------------------
{rank=same;"application";inv_0}
{rank=same;table_4;table_5}
}
Результат: