Graduately/net.c
pepaskopec-blip 6848b22b93 Add network unit 27 on wireless networks and Wi-Fi security.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 13:16:00 +02:00

3907 lines
145 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "maturita.h"
/* ---- Computer networks: subject path, lesson & exercise ------------ */
NetLesson net_lessons[NET_LESSONS] = {
/* UI unit N maps to lesson content: unit 1 = IP/VLSM (extra);
* units 2–27 = source topics (Základní pojmy … bezdrátové sítě). */
{ .n_slides = NET_SLIDES, .unit_page = "netunit1", .ex_page = "netex1" },
{ .n_slides = NET2_SLIDES, .unit_page = "netunit2", .ex_page = "netex2" },
{ .n_slides = NET3_SLIDES, .unit_page = "netunit3", .ex_page = "netex3" },
{ .n_slides = NET4_SLIDES, .unit_page = "netunit4", .ex_page = "netex4" },
{ .n_slides = NET5_SLIDES, .unit_page = "netunit5", .ex_page = "netex5" },
{ .n_slides = NET6_SLIDES, .unit_page = "netunit6", .ex_page = "netex6" },
{ .n_slides = NET7_SLIDES, .unit_page = "netunit7", .ex_page = "netex7" },
{ .n_slides = NET8_SLIDES, .unit_page = "netunit8", .ex_page = "netex8" },
{ .n_slides = NET9_SLIDES, .unit_page = "netunit9", .ex_page = "netex9" },
{ .n_slides = NET10_SLIDES, .unit_page = "netunit10", .ex_page = "netex10" },
{ .n_slides = NET11_SLIDES, .unit_page = "netunit11", .ex_page = "netex11" },
{ .n_slides = NET12_SLIDES, .unit_page = "netunit12", .ex_page = "netex12" },
{ .n_slides = NET13_SLIDES, .unit_page = "netunit13", .ex_page = "netex13" },
{ .n_slides = NET14_SLIDES, .unit_page = "netunit14", .ex_page = "netex14" },
{ .n_slides = NET15_SLIDES, .unit_page = "netunit15", .ex_page = "netex15" },
{ .n_slides = NET16_SLIDES, .unit_page = "netunit16", .ex_page = "netex16" },
{ .n_slides = NET17_SLIDES, .unit_page = "netunit17", .ex_page = "netex17" },
{ .n_slides = NET18_SLIDES, .unit_page = "netunit18", .ex_page = "netex18" },
{ .n_slides = NET19_SLIDES, .unit_page = "netunit19", .ex_page = "netex19" },
{ .n_slides = NET20_SLIDES, .unit_page = "netunit20", .ex_page = "netex20" },
{ .n_slides = NET21_SLIDES, .unit_page = "netunit21", .ex_page = "netex21" },
{ .n_slides = NET22_SLIDES, .unit_page = "netunit22", .ex_page = "netex22" },
{ .n_slides = NET23_SLIDES, .unit_page = "netunit23", .ex_page = "netex23" },
{ .n_slides = NET24_SLIDES, .unit_page = "netunit24", .ex_page = "netex24" },
{ .n_slides = NET25_SLIDES, .unit_page = "netunit25", .ex_page = "netex25" },
{ .n_slides = NET26_SLIDES, .unit_page = "netunit26", .ex_page = "netex26" },
{ .n_slides = NET27_SLIDES, .unit_page = "netunit27", .ex_page = "netex27" },
};
void net_paragraph(GtkWidget *box, const char *text) {
GtkWidget *l = gtk_label_new(text);
gtk_widget_set_halign(l, GTK_ALIGN_START);
gtk_label_set_wrap(GTK_LABEL(l), TRUE);
gtk_widget_add_css_class(l, "ex-prompt");
gtk_box_append(GTK_BOX(box), l);
}
void net_heading(GtkWidget *box, const char *text) {
GtkWidget *l = gtk_label_new(text);
gtk_widget_set_halign(l, GTK_ALIGN_START);
gtk_label_set_wrap(GTK_LABEL(l), TRUE);
gtk_widget_set_margin_top(l, 6);
gtk_widget_add_css_class(l, "ex-sub");
gtk_box_append(GTK_BOX(box), l);
}
/* Note-card slides with text that scales with the window. */
GtkWidget *net_note_host;
int net_note_last_w = -1;
NetLesson *net_notes_target;
void net_lesson_notes_ensure(NetLesson *L) {
if (L->note_kicks)
return;
L->note_kicks = g_array_new(FALSE, FALSE, sizeof(GtkWidget *));
L->note_titles = g_array_new(FALSE, FALSE, sizeof(GtkWidget *));
L->note_bodies = g_array_new(FALSE, FALSE, sizeof(GtkWidget *));
}
void net_note_font(GtkWidget *l, int px) {
PangoAttrList *attrs = pango_attr_list_new();
pango_attr_list_insert(attrs, pango_attr_size_new(px * PANGO_SCALE));
gtk_label_set_attributes(GTK_LABEL(l), attrs);
pango_attr_list_unref(attrs);
}
void net_rescale_lesson_notes(NetLesson *L, int body, int head, int kick) {
if (!L || !L->note_kicks)
return;
for (guint i = 0; i < L->note_kicks->len; i++)
net_note_font(g_array_index(L->note_kicks, GtkWidget *, i), kick);
for (guint i = 0; i < L->note_titles->len; i++)
net_note_font(g_array_index(L->note_titles, GtkWidget *, i), head);
for (guint i = 0; i < L->note_bodies->len; i++)
net_note_font(g_array_index(L->note_bodies, GtkWidget *, i), body);
}
void net_rescale_notes_at(int w) {
int body, head, kick;
if (w < 160)
w = 160;
body = w / 46;
if (body < 14) body = 14;
if (body > 26) body = 26;
head = body + 14;
if (head > 46) head = 46;
kick = body - 3;
if (kick < 11) kick = 11;
for (int i = 0; i < NET_LESSONS; i++)
net_rescale_lesson_notes(&net_lessons[i], body, head, kick);
}
void net_rescale_notes(void) {
int w = net_note_host ? gtk_widget_get_allocated_width(net_note_host) : 0;
net_rescale_notes_at(w);
}
gboolean net_note_tick(GtkWidget *w, GdkFrameClock *clock,
gpointer data) {
int width = gtk_widget_get_allocated_width(w);
(void)clock;
(void)data;
if (width != net_note_last_w) {
net_note_last_w = width;
net_rescale_notes_at(width);
}
return G_SOURCE_CONTINUE;
}
GtkWidget *net_slide_card(const char *cls) {
GtkWidget *l = gtk_label_new(NULL);
gtk_widget_add_css_class(l, cls);
gtk_label_set_wrap(GTK_LABEL(l), TRUE);
gtk_label_set_justify(GTK_LABEL(l), GTK_JUSTIFY_CENTER);
gtk_widget_set_hexpand(l, TRUE);
gtk_widget_set_halign(l, GTK_ALIGN_FILL);
return l;
}
void net_note_kicker(GtkWidget *box, const char *text) {
GtkWidget *l = net_slide_card("notes-kicker");
gtk_label_set_text(GTK_LABEL(l), text);
gtk_box_append(GTK_BOX(box), l);
if (net_notes_target)
g_array_append_val(net_notes_target->note_kicks, l);
}
void net_note_title(GtkWidget *box, const char *text) {
GtkWidget *l = net_slide_card("notes-title");
gtk_label_set_text(GTK_LABEL(l), text);
gtk_box_append(GTK_BOX(box), l);
if (net_notes_target)
g_array_append_val(net_notes_target->note_titles, l);
}
void net_note_line(GtkWidget *box, const char *text, gboolean tip) {
GtkWidget *l = net_slide_card(tip ? "notes-tip" : "notes-body");
gtk_label_set_text(GTK_LABEL(l), text);
gtk_widget_set_margin_top(l, 2);
gtk_box_append(GTK_BOX(box), l);
if (net_notes_target)
g_array_append_val(net_notes_target->note_bodies, l);
}
void net_slide_apply(NetLesson *L) {
char name[16];
if (!L || !L->stack)
return;
g_snprintf(name, sizeof(name), "net_slide%u", L->idx);
gtk_stack_set_visible_child_name(GTK_STACK(L->stack), name);
if (L->prev_btn) {
gtk_button_set_label(GTK_BUTTON(L->prev_btn), tr("net_slide_prev"));
gtk_widget_set_sensitive(L->prev_btn, L->idx > 0);
}
if (L->next_btn) {
gtk_button_set_label(
GTK_BUTTON(L->next_btn),
L->idx + 1 >= L->n_slides ? tr("net_slide_start")
: tr("net_slide_next"));
}
}
void net_lessons_apply_lang(void) {
for (int i = 0; i < NET_LESSONS; i++)
net_slide_apply(&net_lessons[i]);
}
void net_open_unit(GtkButton *button, gpointer data) {
NetLesson *L = data;
(void)button;
if (!L)
return;
L->idx = 0;
net_slide_apply(L);
gtk_stack_set_visible_child_name(main_stack, L->unit_page);
}
void net_slide_prev(GtkButton *button, gpointer data) {
NetLesson *L = data;
(void)button;
if (!L)
return;
if (L->idx > 0) {
L->idx--;
net_slide_apply(L);
}
}
void net_slide_next(GtkButton *button, gpointer data) {
NetLesson *L = data;
(void)button;
if (!L)
return;
if (L->idx + 1 < L->n_slides) {
L->idx++;
net_slide_apply(L);
} else {
gtk_stack_set_visible_child_name(main_stack, L->ex_page);
}
}
GtkWidget *net_scroll;
GtkWidget *net_fixed;
GtkWidget *net_rail;
GtkWidget *net_nodes[NET_UNITS];
GtkWidget *net_labels[NET_UNITS];
double net_cx[NET_UNITS];
double net_cy[NET_UNITS];
int net_cols = 1;
int net_rows = 1;
int net_cw = (int)(2.0 * ROAD_MX + (NET_UNITS - 1) * PATH_SPAC);
int net_ch = (int)(2.0 * ROAD_MY);
guint net_idle;
double net_last_avail = -1.0;
int net_last_cols = -1;
int net_last_rows = -1;
int net_last_cw = -1;
int net_last_ch = -1;
cairo_surface_t *net_rail_cache;
int net_cache_w;
int net_cache_h;
void net_point(double t, double *ox, double *oy) {
int k = (int)t;
double u = t - (double)k;
double u2, u3;
double p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y;
if (k < 0) { k = 0; u = 0.0; }
if (k >= NET_UNITS - 1) { k = NET_UNITS - 2; u = 1.0; }
p1x = net_cx[k]; p1y = net_cy[k];
p2x = net_cx[k + 1]; p2y = net_cy[k + 1];
if (k - 1 >= 0) { p0x = net_cx[k - 1]; p0y = net_cy[k - 1]; }
else { p0x = p1x - (p2x - p1x); p0y = p1y - (p2y - p1y); }
if (k + 2 < NET_UNITS) { p3x = net_cx[k + 2]; p3y = net_cy[k + 2]; }
else { p3x = p2x + (p2x - p1x); p3y = p2y + (p2y - p1y); }
u2 = u * u;
u3 = u2 * u;
*ox = 0.5 * (2.0 * p1x + (-p0x + p2x) * u
+ (2.0 * p0x - 5.0 * p1x + 4.0 * p2x - p3x) * u2
+ (-p0x + 3.0 * p1x - 3.0 * p2x + p3x) * u3);
*oy = 0.5 * (2.0 * p1y + (-p0y + p2y) * u
+ (2.0 * p0y - 5.0 * p1y + 4.0 * p2y - p3y) * u2
+ (-p0y + 3.0 * p1y - 3.0 * p2y + p3y) * u3);
}
void net_path(cairo_t *cr, double t0, double t1) {
const double steps_per_unit = 24.0;
int n = (int)((t1 - t0) * steps_per_unit);
double x, y;
int s;
if (n < 1)
n = 1;
net_point(t0, &x, &y);
cairo_move_to(cr, x, y);
for (s = 1; s <= n; s++) {
net_point(t0 + (t1 - t0) * (double)s / (double)n, &x, &y);
cairo_line_to(cr, x, y);
}
}
void net_geometry(double avail) {
const double phase = 2.0 * G_PI * 1.7 / (double)(NET_UNITS - 1);
int rows;
int r, c, i;
for (rows = 1; rows <= NET_UNITS; rows++) {
int cols = (NET_UNITS + rows - 1) / rows;
if (2.0 * ROAD_MX + (cols - 1) * PATH_SPAC <= avail + 1.0)
break;
}
if (rows > NET_UNITS)
rows = NET_UNITS;
net_rows = rows;
net_cols = (NET_UNITS + rows - 1) / rows;
if (net_cols < 1)
net_cols = 1;
net_cw = (int)(2.0 * ROAD_MX + (net_cols - 1) * PATH_SPAC);
net_ch = (int)(2.0 * ROAD_MY + (rows - 1) * ROAD_GAP);
for (r = 0; r < rows; r++) {
int base = r * net_cols;
int len = MIN(net_cols, NET_UNITS - base);
int fwd = (r % 2) == 0;
for (c = 0; c < len; c++) {
i = base + c;
int cc = fwd ? c : (net_cols - 1 - c);
net_cx[i] = ROAD_MX + cc * PATH_SPAC;
net_cy[i] = ROAD_MY + r * ROAD_GAP
+ ROAD_WAVE * sin((double)i * phase);
}
}
}
void net_apply_layout(void) {
if (!net_fixed)
return;
if (net_cols == net_last_cols && net_rows == net_last_rows &&
net_cw == net_last_cw && net_ch == net_last_ch)
return;
net_last_cols = net_cols;
net_last_rows = net_rows;
net_last_cw = net_cw;
net_last_ch = net_ch;
if (net_rail_cache) {
cairo_surface_destroy(net_rail_cache);
net_rail_cache = NULL;
}
for (int i = 0; i < NET_UNITS; i++) {
if (!net_nodes[i] || !net_labels[i])
continue;
gtk_fixed_move(GTK_FIXED(net_fixed), net_nodes[i],
(int)(net_cx[i] - NODE_SIZE / 2.0),
(int)(net_cy[i] - NODE_SIZE / 2.0));
gtk_fixed_move(GTK_FIXED(net_fixed), net_labels[i],
(int)(net_cx[i] - (PATH_SPAC - 20.0) / 2.0),
(int)(net_cy[i] + NODE_SIZE / 2.0 + 10.0));
}
gtk_widget_set_size_request(net_fixed, net_cw, net_ch);
gtk_widget_set_size_request(net_rail, net_cw, net_ch);
gtk_fixed_move(GTK_FIXED(net_fixed), net_rail, 0, 0);
gtk_widget_queue_draw(net_rail);
}
void net_relayout(void) {
GtkAdjustment *hadj;
double avail;
if (!net_scroll)
return;
hadj = gtk_scrolled_window_get_hadjustment(
GTK_SCROLLED_WINDOW(net_scroll));
avail = gtk_adjustment_get_page_size(hadj);
if (avail < 1.0)
return;
if (fabs(avail - net_last_avail) < 1.0)
return;
net_last_avail = avail;
net_geometry(avail);
net_apply_layout();
}
gboolean net_relayout_idle(gpointer data) {
(void)data;
net_idle = 0;
net_relayout();
return G_SOURCE_REMOVE;
}
void net_relayout_later(void) {
if (net_idle == 0)
net_idle = g_idle_add(net_relayout_idle, NULL);
}
void net_adjust_notify(GtkAdjustment *adj, GParamSpec *ps,
gpointer data) {
(void)adj;
(void)ps;
(void)data;
net_relayout_later();
}
void net_render_rail_to(cairo_t *cr) {
const double t_end = (double)(NET_UNITS - 1);
const Rgb mauve = color_from_hex(app_theme.accent);
const Rgb rail = color_from_hex(app_theme.rail);
const Rgb muted = color_from_hex(app_theme.subtext);
double hx, hy;
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
cairo_paint(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
net_point(0.0, &hx, &hy);
draw_node_halo(cr, hx, hy, NODE_SIZE * 1.05,
mauve.r, mauve.g, mauve.b, 0.18);
cairo_new_path(cr);
net_path(cr, 0.0, t_end);
cairo_set_line_width(cr, 16);
cairo_set_source_rgb(cr, rail.r, rail.g, rail.b);
cairo_stroke(cr);
cairo_set_source_rgba(cr, muted.r, muted.g, muted.b, 0.17);
cairo_set_dash(cr, (double[]){2.0, 40.0}, 2, 0.0);
cairo_new_path(cr);
net_path(cr, 0.0, t_end);
cairo_stroke(cr);
cairo_set_dash(cr, NULL, 0, 0.0);
}
void net_draw_rail(GtkDrawingArea *area, cairo_t *cr,
int width, int height, gpointer data) {
(void)area;
(void)width;
(void)height;
(void)data;
if (!net_rail_cache || net_cache_w != net_cw || net_cache_h != net_ch) {
cairo_t *rcr;
if (net_rail_cache)
cairo_surface_destroy(net_rail_cache);
net_cache_w = net_cw;
net_cache_h = net_ch;
if (net_cache_w < 1)
net_cache_w = 1;
if (net_cache_h < 1)
net_cache_h = 1;
net_rail_cache = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
net_cache_w, net_cache_h);
rcr = cairo_create(net_rail_cache);
net_render_rail_to(rcr);
cairo_destroy(rcr);
}
cairo_set_source_surface(cr, net_rail_cache, 0, 0);
cairo_paint(cr);
}
void net_rail_theme_reset(void) {
if (net_rail_cache) {
cairo_surface_destroy(net_rail_cache);
net_rail_cache = NULL;
}
if (net_rail)
gtk_widget_queue_draw(net_rail);
}
void net_add_node(GtkFixed *fixed, int index) {
int num = index + 1;
gboolean locked = index >= NET_LESSONS;
GtkWidget *card;
GtkWidget *vbox;
GtkWidget *number;
GtkWidget *icon;
GtkWidget *name;
char *text;
static const char *unit_keys[NET_LESSONS] = {
"net_unit1", "net_unit2", "net_unit3", "net_unit4", "net_unit5",
"net_unit6", "net_unit7", "net_unit8", "net_unit9", "net_unit10",
"net_unit11", "net_unit12", "net_unit13", "net_unit14", "net_unit15",
"net_unit16", "net_unit17", "net_unit18", "net_unit19", "net_unit20",
"net_unit21", "net_unit22", "net_unit23", "net_unit24", "net_unit25",
"net_unit26", "net_unit27"
};
card = gtk_button_new();
gtk_widget_add_css_class(card, "unit-node");
gtk_widget_set_can_focus(card, FALSE);
gtk_widget_set_sensitive(card, !locked);
gtk_widget_set_size_request(card, (int)NODE_SIZE, (int)NODE_SIZE);
if (locked)
gtk_widget_add_css_class(card, "locked");
else
gtk_widget_add_css_class(card, "current");
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
gtk_widget_set_halign(vbox, GTK_ALIGN_CENTER);
gtk_widget_set_valign(vbox, GTK_ALIGN_CENTER);
gtk_button_set_child(GTK_BUTTON(card), vbox);
text = g_strdup_printf("%d", num);
number = gtk_label_new(text);
g_free(text);
gtk_widget_add_css_class(number, "unit-number");
gtk_box_append(GTK_BOX(vbox), number);
if (locked) {
icon = icon_area_new(draw_lock_icon, 0.3451, 0.3569, 0.4392, 16);
gtk_box_append(GTK_BOX(vbox), icon);
} else {
icon = icon_area_new(draw_check_icon, 0.1176, 0.1176, 0.1804, 18);
gtk_widget_set_visible(icon, FALSE);
gtk_box_append(GTK_BOX(vbox), icon);
net_lessons[index].done_icon = icon;
g_signal_connect(card, "clicked", G_CALLBACK(net_open_unit),
&net_lessons[index]);
}
net_nodes[index] = card;
gtk_fixed_put(fixed, card, 0, 0);
name = gtk_label_new(NULL);
gtk_widget_set_size_request(name, (int)(PATH_SPAC - 20.0), -1);
gtk_widget_set_halign(name, GTK_ALIGN_CENTER);
gtk_label_set_justify(GTK_LABEL(name), GTK_JUSTIFY_CENTER);
gtk_label_set_wrap(GTK_LABEL(name), TRUE);
gtk_widget_add_css_class(name, "unit-name");
if (index < NET_LESSONS) {
i18n_bind(name, unit_keys[index], 0);
} else {
gtk_widget_add_css_class(name, "unit-name-locked");
}
net_labels[index] = name;
gtk_fixed_put(fixed, name, 0, 0);
}
GtkWidget *build_netmap_page(void) {
GtkWidget *page;
GtkWidget *scroll;
GtkWidget *wrap;
GtkWidget *fixed;
GtkWidget *rail;
GtkAdjustment *ha;
GtkAdjustment *va;
net_geometry(1000.0);
page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_hexpand(page, TRUE);
gtk_widget_set_vexpand(page, TRUE);
gtk_widget_set_margin_start(page, 32);
gtk_widget_set_margin_end(page, 32);
gtk_widget_set_margin_top(page, 24);
gtk_widget_set_margin_bottom(page, 24);
gtk_box_append(GTK_BOX(page),
top_bar("subjects", "Správa počítačových sítí", "net_sub"));
scroll = gtk_scrolled_window_new();
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_widget_set_vexpand(scroll, TRUE);
gtk_widget_set_margin_top(scroll, 14);
gtk_box_append(GTK_BOX(page), scroll);
net_scroll = scroll;
wrap = gtk_center_box_new();
gtk_widget_set_vexpand(wrap, TRUE);
gtk_widget_set_hexpand(wrap, TRUE);
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scroll), wrap);
fixed = gtk_fixed_new();
gtk_widget_set_halign(fixed, GTK_ALIGN_CENTER);
gtk_widget_set_valign(fixed, GTK_ALIGN_CENTER);
gtk_widget_set_size_request(fixed, net_cw, net_ch);
gtk_center_box_set_center_widget(GTK_CENTER_BOX(wrap), fixed);
net_fixed = fixed;
rail = gtk_drawing_area_new();
gtk_widget_set_size_request(rail, net_cw, net_ch);
gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(rail), net_draw_rail,
NULL, NULL);
gtk_fixed_put(GTK_FIXED(fixed), rail, 0, 0);
net_rail = rail;
for (int i = 0; i < NET_UNITS; i++)
net_add_node(GTK_FIXED(fixed), i);
ha = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(scroll));
va = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scroll));
g_signal_connect(ha, "notify::page-size",
G_CALLBACK(net_adjust_notify), NULL);
g_signal_connect(va, "notify::page-size",
G_CALLBACK(net_adjust_notify), NULL);
net_relayout_later();
refresh_net_completion_ui();
return page;
}
GtkWidget *build_net_unit_page(NetLesson *L, const char *title_key,
const char *sub_key, const NetSlide *slides,
guint n_slides) {
GtkWidget *page;
GtkWidget *scroll;
GtkWidget *nav;
net_lesson_notes_ensure(L);
net_notes_target = L;
L->n_slides = n_slides;
page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_margin_start(page, 28);
gtk_widget_set_margin_end(page, 28);
gtk_widget_set_margin_top(page, 20);
gtk_widget_set_margin_bottom(page, 20);
/* sub_key must be a stable string (i18n_bind keeps the pointer). */
gtk_box_append(GTK_BOX(page), top_bar("netmap", title_key, sub_key));
scroll = gtk_scrolled_window_new();
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_widget_set_vexpand(scroll, TRUE);
gtk_widget_set_margin_top(scroll, 10);
gtk_box_append(GTK_BOX(page), scroll);
L->stack = gtk_stack_new();
gtk_stack_set_transition_type(GTK_STACK(L->stack),
GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT);
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scroll), L->stack);
net_note_host = L->stack;
for (guint s = 0; s < n_slides; s++) {
GtkWidget *stage = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
GtkWidget *card;
char name[16];
gtk_widget_set_vexpand(stage, TRUE);
g_snprintf(name, sizeof(name), "net_slide%u", s);
gtk_stack_add_named(GTK_STACK(L->stack), stage, name);
card = gtk_box_new(GTK_ORIENTATION_VERTICAL, 16);
gtk_widget_add_css_class(card, "notes-card");
gtk_widget_set_valign(card, GTK_ALIGN_CENTER);
gtk_box_append(GTK_BOX(stage), card);
net_note_kicker(card, slides[s].kicker);
net_note_title(card, slides[s].title);
for (int i = 0; i < 8 && slides[s].line[i]; i++)
net_note_line(card, slides[s].line[i], FALSE);
if (slides[s].tip)
net_note_line(card, slides[s].tip, TRUE);
}
gtk_widget_add_tick_callback(L->stack, net_note_tick, NULL, NULL);
net_note_last_w = -1;
net_rescale_notes();
net_notes_target = NULL;
nav = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
gtk_box_set_homogeneous(GTK_BOX(nav), TRUE);
gtk_widget_set_margin_top(nav, 10);
gtk_box_append(GTK_BOX(page), nav);
L->prev_btn = gtk_button_new_with_label(tr("net_slide_prev"));
gtk_widget_add_css_class(L->prev_btn, "btn-primary");
g_signal_connect(L->prev_btn, "clicked", G_CALLBACK(net_slide_prev), L);
gtk_box_append(GTK_BOX(nav), L->prev_btn);
L->next_btn = gtk_button_new_with_label(tr("net_slide_next"));
gtk_widget_add_css_class(L->next_btn, "btn-primary");
g_signal_connect(L->next_btn, "clicked", G_CALLBACK(net_slide_next), L);
gtk_box_append(GTK_BOX(nav), L->next_btn);
L->idx = 0;
net_slide_apply(L);
return page;
}
GtkWidget *build_net_unit1_page(void) {
static const NetSlide slides[NET_SLIDES] = {
{
"1 / 4 • VLSM", "Podsíťování sítí",
"Tip: prefix /n = počet jedniček v masce. /24 = 255.255.255.0",
{
"Cíl: rozdělit jednu IP síť na menší podsítě podle počtu uzlů.",
"Pamatuj si tři role adres v každém bloku:",
"síťová = první adresa bloku",
"broadcast = poslední adresa bloku",
"uzly = vše mezi nimi (síť + 1 až broadcast − 1)",
NULL,
},
},
{
"2 / 4 • Velikosti", "Jak velký blok potřebuji?",
"Počet bitů pro uzly h = log₂(velikost), prefix = 32 − h",
{
"Pro X uzlů potřebuješ blok, do kterého se vejde X + 2 adresy "
"(síť a broadcast).",
"Velikost bloku je vždy mocnina dvojky – vezmi nejmenší blok, "
"který je větší nebo roven X + 2.",
"60 uzlů → 62 → blok 64 → /26",
"30 uzlů → 32 → blok 32 → /27",
"14 uzlů → 16 → blok 16 → /28",
"7 uzlů → 9 → blok 16 → /28",
NULL,
},
},
{
"3 / 4 • Postup", "Jak na to krok za krokem",
NULL,
{
"1. Seřaď podsítě od největší po nejmenší.",
"2. Pro každou najdi potřebný prefix.",
"3. Začni na síťové adrese ze zadání.",
"4. Rozsah podsítě = od síťové adresy po broadcast.",
"5. Rozsah uzlů = síťová + 1 až broadcast − 1.",
"6. Posuň se hned za broadcast a pokračuj dál.",
NULL,
},
},
{
"4 / 4 • Příklad", "Ukázka: 10.0.0.0/24",
"A: 60 uzlů, B: 30, C: 14, D: 7",
{
"A → 10.0.0.0/26 uzly 10.0.0.1–10.0.0.62 "
"broadcast 10.0.0.63",
"B → 10.0.0.64/27 uzly 10.0.0.65–10.0.0.94 "
"broadcast 10.0.0.95",
"C → 10.0.0.96/28 uzly 10.0.0.97–10.0.0.110 "
"broadcast 10.0.0.111",
"D → 10.0.0.112/28 uzly 10.0.0.113–10.0.0.126 "
"broadcast 10.0.0.127",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[0], "net_unit1", "net_unit1_sub",
slides, NET_SLIDES);
}
GtkWidget *build_net_unit2_page(void) {
static const NetSlide slides[NET2_SLIDES] = {
{
"1 / 5 • Jednotky", "Bit, byte a počítačová síť",
"Tip: 1 B = 8 b → 2⁸ = 256 možných hodnot",
{
"Bit (1 b): základní jednotka informace – 0 nebo 1.",
"0 = nevede proud, 1 = vede proud.",
"Byte (1 B): 1 B = 8 b, nabývá 256 hodnot.",
"Počítačová síť: propojení uzlů (PC a dalších prvků).",
"Vyžaduje hardwarové i softwarové prostředky.",
NULL,
},
},
{
"2 / 5 • Propojení", "Trvalé, dočasné a důvody zapojení",
NULL,
{
"Trvalé propojení: kabely – síť zůstává připojená i po přenosu.",
"Dočasné propojení: modem, Wi‑Fi – po přenosu se odpojuje.",
"Důvody zapojení do sítě:",
"sdílení dat (nutná podpora aplikací)",
"sdílení HW (tiskárny, disky) a SW (databáze)",
"vyšší spolehlivost, bezpečnost (přístupová práva)",
"komunikace (e‑mail, hlas)",
NULL,
},
},
{
"3 / 5 • Pojmy", "Terminologie sítí",
"Architektura = topologie + standard",
{
"Uzel: jakékoli zařízení (stanice, server, aktivní prvek).",
"Topologie: způsob propojení (hvězda, kruh, sběrnice).",
"Standard: normy pro zpracování dat.",
"Architektura: topologie + standard.",
NULL,
},
},
{
"4 / 5 • Rozlehlost", "WAN, MAN a LAN",
NULL,
{
"WAN: rozsáhlé sítě (státy, kontinenty), např. internet.",
"MAN: městské sítě – propojují lokální sítě.",
"LAN: lokální sítě (budova), kabeláž v řádu km,",
"jednotná architektura.",
NULL,
},
},
{
"5 / 5 • Uzly", "Server, stanice a peer‑to‑peer",
NULL,
{
"Server: nadřazený, řídící, poskytuje služby, vyšší výkon.",
"Pracovní stanice: pro uživatele, jednodušší konfigurace.",
"Peer‑to‑peer: síť bez serverů – jen stanice,",
"které sdílejí data a tiskárny.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[1], "net_unit2", "net_unit2_sub",
slides, NET2_SLIDES);
}
GtkWidget *build_net_unit3_page(void) {
static const NetSlide slides[NET3_SLIDES] = {
{
"1 / 4 • Servery", "Role serverů a typy podle služby",
NULL,
{
"Servery ověřují uživatele a povolují přístup.",
"Souborový server (fileserver): sdílení souborů.",
"Tiskový server: sdílení tiskáren.",
"Poštovní server: e‑mailové služby.",
"Databázový server: správa a přístup k databázím.",
NULL,
},
},
{
"2 / 4 • Rozložení", "Centralizovaný a distribuovaný server",
NULL,
{
"Centralizovaný: jeden server v síti.",
"Výpadek = nedostupnost služby.",
"Distribuovaný: více serverů, každý obsluhuje část.",
"Vyšší spolehlivost a rychlost.",
NULL,
},
},
{
"3 / 4 • Využití", "Vyhrazený, nevyhrazený a mainframe",
NULL,
{
"Nevyhrazený: slouží i jako stanice (levnější).",
"Vyhrazený: jen síťové služby – vysoký výkon a bezpečnost,",
"typicky v racku.",
"Mainframe: obří sálové počítače (IBM, Siemens),",
"stovky procesorů, OS Unix (AIX, Solaris).",
"Použití: banky a státní správa.",
NULL,
},
},
{
"4 / 4 • Cloud", "Cloudové služby",
"Tip: SaaS = software jako služba",
{
"Cloud: globální síť vzdálených serverů propojených internetem.",
"Fungují jako jeden systém: ukládání dat, SaaS,",
"streamování, webová pošta.",
"Přístup online z jakéhokoli zařízení.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[2], "net_unit3", "net_unit3_sub",
slides, NET3_SLIDES);
}
GtkWidget *build_net_unit4_page(void) {
static const NetSlide slides[NET4_SLIDES] = {
{
"1 / 4 • Přenos", "Paralelní a sériový přenos",
NULL,
{
"Paralelní: více bitů současně po více vodičích.",
"Problém: přeslechy (rušení) při delších kabelech",
"a vysokých frekvencích.",
"Sériový: bit po bitu po jednom vodiči.",
"Umožňuje vyšší frekvence i délky – celkově rychlejší.",
NULL,
},
},
{
"2 / 4 • Časování", "Asynchronní přenos",
"Tip: Start-bit = 0, Stop-bit = 1",
{
"Data se posílají v blocích (znaky 5–8 bitů).",
"Start-bit (0) synchronizuje začátek znaku.",
"Stop-bit (1) znak ukončuje.",
NULL,
},
},
{
"3 / 4 • Časování", "Synchronní přenos",
NULL,
{
"Řízeno společným hodinovým signálem.",
"Přesné časování mezi vysílačem a přijímačem.",
NULL,
},
},
{
"4 / 4 • Zabezpečení", "Parita, checksum a CRC",
"Tip: CRC je nejbezpečnější z těchto tří metod",
{
"Parita: nejslabší – přidá bit pro sudý/lichý počet jedniček.",
"Checksum: součet znaků jako dvojkových čísel.",
"CRC (cyklické kódy): nejbezpečnější,",
"počítá se z jednotlivých bitů v bloku.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[3], "net_unit4", "net_unit4_sub",
slides, NET4_SLIDES);
}
GtkWidget *build_net_unit5_page(void) {
static const NetSlide slides[NET5_SLIDES] = {
{
"1 / 4 • Signál", "Analogový a digitální signál",
"Tip: f = 1/T",
{
"Analogový: spojitý, nabývá libovolných hodnot.",
"Digitální: diskrétní, hodnoty 0 a 1.",
"Parametry signálu:",
"perioda T, frekvence f = 1/T,",
"amplituda A, fázový posun Φ.",
NULL,
},
},
{
"2 / 4 • Modulace", "Základní typy modulace",
"Modulace = přenos v přeloženém pásmu",
{
"AM – amplitudová modulace.",
"FM – frekvenční modulace.",
"PM – fázová modulace.",
NULL,
},
},
{
"3 / 4 • Kombinované", "QPSK a 256-QAM",
NULL,
{
"QPSK: 2 bity v jednom prvku (symbolu).",
"256-QAM: 8 bitů v jednom prvku.",
NULL,
},
},
{
"4 / 4 • Rychlosti", "Modulační, přenosová a šířka pásma",
NULL,
{
"Modulační rychlost: počet změn signálu za sekundu [Baud, Bd/s].",
"Přenosová rychlost: velikost přenesené informace [bit/s, bps].",
"Šířka pásma: rozsah frekvencí –",
"určuje maximální možnou rychlost.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[4], "net_unit5", "net_unit5_sub",
slides, NET5_SLIDES);
}
GtkWidget *build_net_unit6_page(void) {
static const NetSlide slides[NET6_SLIDES] = {
{
"1 / 4 • Spoj", "Datový spoj",
NULL,
{
"Datový spoj umožňuje výměnu informací.",
"Může být dvoubodový nebo vícebodový.",
NULL,
},
},
{
"2 / 4 • Cesta", "Přenosová cesta",
NULL,
{
"Přenosová cesta je fyzické médium.",
"Příklady: metalické nebo optické kabely,",
"mikrovlny, družice.",
NULL,
},
},
{
"3 / 4 • Kanál a okruh", "Přenosový kanál a okruh",
"Tip: okruh = dva kanály → obousměrný přenos",
{
"Přenosový kanál: jednosměrný souhrn prostředků pro spojení.",
"Okruh: tvořen dvěma kanály – umožňuje obousměrný přenos.",
NULL,
},
},
{
"4 / 4 • Trunking", "Spojování cest",
NULL,
{
"Trunking spojuje více cest do jednoho okruhu.",
"Cíl: zvýšení šířky pásma.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[5], "net_unit6", "net_unit6_sub",
slides, NET6_SLIDES);
}
GtkWidget *build_net_unit7_page(void) {
static const NetSlide slides[NET7_SLIDES] = {
{
"1 / 4 • Multiplex", "Rozdělení kanálu",
NULL,
{
"Multiplex: rozdělení jednoho kanálu",
"na více logických podkanálů.",
NULL,
},
},
{
"2 / 4 • Typy", "FDM, TDM a STDM",
NULL,
{
"FDM (frekvenční): každému kanálu část frekvenčního pásma.",
"TDM (časový): každému kanálu vyhrazený časový slot.",
"STDM (statistický): kapacita dle potřeby (paketový přenos),",
"negarantuje 100% dostupnost.",
NULL,
},
},
{
"3 / 4 • Směry", "Simplex, poloduplex a duplex",
NULL,
{
"Simplex: jen jeden směr (např. optické vlákno).",
"Poloduplex (half-duplex): oběma směry, ne současně.",
"Duplex (full-duplex): oběma směry současně.",
NULL,
},
},
{
"4 / 4 • Agregace", "Sdílení kapacity",
NULL,
{
"Agregace: sdílení kapacity kanálu více uživateli.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[6], "net_unit7", "net_unit7_sub",
slides, NET7_SLIDES);
}
GtkWidget *build_net_unit8_page(void) {
static const NetSlide slides[NET8_SLIDES] = {
{
"1 / 4 • Okruhy", "Přepojování okruhů",
"Tip: spojovaná služba – jako telefon",
{
"Cesta se vytýčí předem (spojovaná služba).",
"Kapacita je garantována.",
"Přenos probíhá v reálném čase.",
NULL,
},
},
{
"2 / 4 • Pakety", "Přepojování paketů",
NULL,
{
"Data se dělí na pakety s adresami.",
"Každý paket může jít jinou cestou.",
NULL,
},
},
{
"3 / 4 • Hodnocení", "Výhody a nevýhody paketů",
NULL,
{
"Výhody: reakce na zátěž, lepší využití kapacity.",
"Nevýhody: negarantuje pořadí ani plynulost.",
"Nevhodné pro video v reálném čase.",
NULL,
},
},
{
"4 / 4 • Virtuální", "Virtuální spoje",
NULL,
{
"Cesta je vytýčena předem,",
"ale prostředky se využívají jen při průchodu paketu.",
"Výsledek: zrychlení datagramů.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[7], "net_unit8", "net_unit8_sub",
slides, NET8_SLIDES);
}
GtkWidget *build_net_unit9_page(void) {
static const NetSlide slides[NET9_SLIDES] = {
{
"1 / 4 • Proč", "Standardizace a dekompozice",
NULL,
{
"Standardizace zajišťuje kompatibilitu mezi výrobci.",
"Dekompozice: rozklad složitého problému přenosu na vrstvy.",
NULL,
},
},
{
"2 / 4 • Vrstvy", "Komunikace mezi vrstvami",
"Tip: SAP = Service Access Point",
{
"Vrstvy komunikují jen se sousedy přes rozhraní (SAP).",
NULL,
},
},
{
"3 / 4 • Protokol", "Pravidla komunikace",
NULL,
{
"Protokol: pravidla komunikace mezi stejnými vrstvami",
"na různých uzlech.",
NULL,
},
},
{
"4 / 4 • Jednotky", "Hlavičky a PDU",
NULL,
{
"Každá vrstva přidá k datům hlavičku (header).",
"Rámec – linková vrstva.",
"Paket – síťová vrstva.",
"Segment – transportní vrstva.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[8], "net_unit9", "net_unit9_sub",
slides, NET9_SLIDES);
}
GtkWidget *build_net_unit10_page(void) {
static const NetSlide slides[NET10_SLIDES] = {
{
"1 / 3 • ISO/OSI", "Sedmivrstvý model",
NULL,
{
"ISO/OSI: 7vrstvý model.",
"Je univerzální – popisuje komunikaci obecně.",
"V praxi je ale pomalejší: každá vrstva řešila spolehlivost.",
NULL,
},
},
{
"2 / 3 • TCP/IP", "Praktická architektura",
NULL,
{
"TCP/IP: architektura, která zvítězila v praxi.",
"Vycházela ze skutečných potřeb sítí.",
"Spolehlivost řeší až vyšší vrstvy.",
NULL,
},
},
{
"3 / 3 • Srovnání", "Proč zvítězil TCP/IP",
"Tip: méně režie na nižších vrstvách = rychlejší provoz",
{
"ISO/OSI: teoretický, univerzální, těžší a pomalejší.",
"TCP/IP: praktický, jednodušší dělení odpovědností.",
"Proto se TCP/IP stal základem dnešního internetu.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[9], "net_unit10", "net_unit10_sub",
slides, NET10_SLIDES);
}
GtkWidget *build_net_unit11_page(void) {
static const NetSlide slides[NET11_SLIDES] = {
{
"1 / 8 • Přehled", "Tři skupiny vrstev",
"Tip: přenos → přizpůsobení → aplikace",
{
"Vrstvy orientované na přenos: fyzická, spojová, síťová.",
"Přizpůsobovací vrstva: transportní.",
"Vrstvy orientované na aplikace: relační, prezentační,",
"aplikační.",
NULL,
},
},
{
"2 / 8 • Fyzická", "Přenos bitů",
NULL,
{
"Přenos bitů po médiu.",
"Definuje napětí, kabely, konektory, kódování a modulaci.",
"Řeší také duplex / simplex.",
NULL,
},
},
{
"3 / 8 • Spojová", "Rámce a MAC",
"Tip: podvrstvy MAC (přístup k médiu) a LLC (logické řízení)",
{
"Tvorba rámců a fyzické (MAC) adresy.",
"Kontrola chyb (CRC) a řízení toku mezi sousedními uzly.",
"Podvrstvy: MAC a LLC.",
NULL,
},
},
{
"4 / 8 • Síťová", "Směrování paketů",
NULL,
{
"Směrování (routing) paketů.",
"Funguje i v sítích bez přímého spojení mezi uzly.",
NULL,
},
},
{
"5 / 8 • Transportní", "Segmenty end-to-end",
"Tip: v routerech transportní vrstva není",
{
"Rozklad zpráv na segmenty a jejich zpětné složení.",
"Kontrola pořadí a náprava chyb.",
"Existuje jen v koncových uzlech – není v routerech.",
NULL,
},
},
{
"6 / 8 • Relační", "Relace a dialog",
NULL,
{
"Navazuje, udržuje a ukončuje relace.",
"Řídí dialog („neskákat si do řeči“).",
"Synchronizace – navázání po přerušení.",
NULL,
},
},
{
"7 / 8 • Prezentační", "Formát dat",
NULL,
{
"Formátování dat (např. ASCII).",
"Komprese a šifrování.",
"Převod mezi různými standardy.",
NULL,
},
},
{
"8 / 8 • Aplikační", "Rozhraní pro programy",
NULL,
{
"Rozhraní pro aplikace a služby.",
"Například e-mail, HTTP, FTP nebo terminál.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[10], "net_unit11", "net_unit11_sub",
slides, NET11_SLIDES);
}
GtkWidget *build_net_unit12_page(void) {
static const NetSlide slides[NET12_SLIDES] = {
{
"1 / 6 • Mapování", "TCP/IP vs ISO/OSI",
NULL,
{
"Aplikační TCP/IP = aplikační + prezentační + relační ISO/OSI.",
"Transportní TCP/IP = transportní ISO/OSI.",
"Síťová (internetová) = síťová ISO/OSI.",
"Vrstva síťového rozhraní = linková + fyzická ISO/OSI.",
NULL,
},
},
{
"2 / 6 • Vznik", "Nejprve protokoly",
"Tip: opačný postup než u ISO/OSI",
{
"Nejprve vznikly protokoly pro Internet.",
"Až poté byl definován model TCP/IP.",
"U ISO/OSI to bylo naopak: nejdřív model, pak protokoly.",
NULL,
},
},
{
"3 / 6 • Aplikace", "Aplikační protokoly",
NULL,
{
"HTTP, HTTPS, FTP, DHCP, DNS.",
"Pošta: POP3, IMAP, SMTP.",
NULL,
},
},
{
"4 / 6 • Transport", "TCP a UDP",
NULL,
{
"TCP: spolehlivý, spojovaný.",
"UDP: nespolehlivý, rychlý.",
NULL,
},
},
{
"5 / 6 • Síť", "Internetové protokoly",
NULL,
{
"IP – základní přenos paketů.",
"ICMP, ARP.",
"Směrování: RIP, OSPF.",
NULL,
},
},
{
"6 / 6 • Rozhraní", "Síťové rozhraní",
NULL,
{
"Ethernet, Token Ring, PPP, ATM.",
"Odpovídá linkové a fyzické vrstvě ISO/OSI.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[11], "net_unit12", "net_unit12_sub",
slides, NET12_SLIDES);
}
GtkWidget *build_net_unit13_page(void) {
static const NetSlide slides[NET13_SLIDES] = {
{
"1 / 4 • Přehled", "Topologie sítě",
NULL,
{
"Topologie popisuje, jak jsou uzly propojené.",
"Základní typy: sběrnice, hvězda a kruh.",
NULL,
},
},
{
"2 / 4 • Sběrnice", "Bus",
"Tip: dříve typicky koaxiální kabel",
{
"Médium sdílí všichni – jednoduchá a levná topologie.",
"Malá délka kabelů.",
"Nevýhody: nízká bezpečnost (všichni slyší vše).",
"Přerušení kabelu nebo terminátoru vyřadí celou síť.",
NULL,
},
},
{
"3 / 4 • Hvězda", "Star",
"Tip: kroucená dvoulinka nebo optika",
{
"Uzly jdou přes centrální prvek (hub nebo switch).",
"Výhody: odolnost proti poruchám kabelů k uzlům,",
"snadná diagnostika.",
"Nevýhody: aktivní prvky a více kabeláže.",
NULL,
},
},
{
"4 / 4 • Kruh", "Ring",
"Tip: často zdvojený kruh pro odolnost",
{
"Kabely tvoří souvislý kruh.",
"Zprávy obíhají, dokud nenajdou adresáta.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[12], "net_unit13", "net_unit13_sub",
slides, NET13_SLIDES);
}
GtkWidget *build_net_unit14_page(void) {
static const NetSlide slides[NET14_SLIDES] = {
{
"1 / 5 • Princip", "Světlo místo proudu",
"Tip: obousměrný provoz = dvě vlákna",
{
"Elektrické impulsy se převádí na světlo (LED nebo laser).",
"Zpět je zachytí fotodioda.",
"Přenos jedním vláknem je jednosměrný.",
NULL,
},
},
{
"2 / 5 • Výhody", "Proč optika",
NULL,
{
"Imunita vůči elektromagnetickému rušení.",
"Obrovská šířka pásma a dosah až kolem 100 km.",
"Lepší bezpečnost proti odposlechu.",
"Malý průměr a nízká váha.",
NULL,
},
},
{
"3 / 5 • Nevýhody", "Cena a montáž",
NULL,
{
"Náročná montáž.",
"Dražší aktivní prvky a konektory.",
NULL,
},
},
{
"4 / 5 • MM", "Mnohovidová vlákna",
NULL,
{
"Větší jádro: 50 / 62,5 µm.",
"Více cest světla (vidů).",
"Levnější zdroje – typicky LED.",
NULL,
},
},
{
"5 / 5 • SM", "Jednovidová vlákna",
NULL,
{
"Malé jádro: 7–10 µm.",
"Jen jeden paprsek osou vlákna.",
"Velký dosah, vyžaduje laser.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[13], "net_unit14", "net_unit14_sub",
slides, NET14_SLIDES);
}
GtkWidget *build_net_unit15_page(void) {
static const NetSlide slides[NET15_SLIDES] = {
{
"1 / 3 • Primární", "Ochrana 250 µm",
NULL,
{
"Primární ochrana má průměr 250 µm.",
"Chrání samotné vlákno hned po výrobě.",
NULL,
},
},
{
"2 / 3 • Sekundární", "Ochrana 900 µm",
"Tip: těsná pro svislé, volná pro vodorovné instalace",
{
"Sekundární ochrana má průměr 900 µm.",
"Těsná varianta: vhodné pro svislé instalace.",
"Volná varianta: vhodné pro vodorovné instalace.",
NULL,
},
},
{
"3 / 3 • Montáž", "Lámání a sváření",
"Tip: kolmost lomu do 0,5°",
{
"Vyžaduje precizní lámání lámačkou.",
"Spojování se dělá svářečkou optických vláken.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[14], "net_unit15", "net_unit15_sub",
slides, NET15_SLIDES);
}
GtkWidget *build_net_unit16_page(void) {
static const NetSlide slides[NET16_SLIDES] = {
{
"1 / 4 • Kolize", "Sdílené médium",
NULL,
{
"Kolize nastane, když na sdíleném médiu vysílá více uzlů najednou.",
NULL,
},
},
{
"2 / 4 • Aloha", "Vysílej kdykoliv",
"Tip: časté kolize, primitivní metoda",
{
"Uzel vysílá kdykoliv chce.",
"Když nepřijde potvrzení, pošle data znovu.",
"Kolize jsou časté.",
NULL,
},
},
{
"3 / 4 • CSMA/CD", "Ethernet",
"Tip: Carrier Sense + Collision Detection",
{
"Nejdřív se poslouchá nosná (Carrier Sense).",
"Je-li ticho, uzel vysílá.",
"Při kolizi se vysílání zastaví a zkusí se znovu",
"po náhodném čase.",
NULL,
},
},
{
"4 / 4 • CSMA/CA", "Wi-Fi",
"Tip: Collision Avoidance přes RTS/CTS",
{
"Předchází kolizím (Collision Avoidance).",
"RTS (Request to Send) a CTS (Clear to Send)",
"rezervují médium před vysíláním.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[15], "net_unit16", "net_unit16_sub",
slides, NET16_SLIDES);
}
GtkWidget *build_net_unit17_page(void) {
static const NetSlide slides[NET17_SLIDES] = {
{
"1 / 7 • Přehled", "Aktivní prvky",
NULL,
{
"Aktivní prvky zpracovávají nebo převádí signál / data.",
"Liší se podle vrstvy ISO/OSI, na které pracují.",
NULL,
},
},
{
"2 / 7 • Repeater", "Opakovač",
"Tip: fyzická vrstva",
{
"Zesiluje signál a tím zvyšuje dosah.",
NULL,
},
},
{
"3 / 7 • Transceiver", "Konvertor",
"Tip: fyzická vrstva",
{
"Převádí signál mezi různými médii.",
"Například metaliku na optiku.",
NULL,
},
},
{
"4 / 7 • Hub", "Rozbočovač",
"Tip: fyzická vrstva – „hloupý“ prvek",
{
"Co přijme na jednom portu, rozešle do všech ostatních.",
NULL,
},
},
{
"5 / 7 • Bridge/Switch", "Most a přepínač",
"Tip: linková vrstva – rámce a MAC",
{
"Pracují s rámci a MAC adresami.",
"Switch dělí síť na kolizní domény.",
NULL,
},
},
{
"6 / 7 • Router", "Směrovač",
"Tip: síťová vrstva – pakety a IP",
{
"Pracuje s pakety a IP adresami.",
"Propojuje různé sítě.",
NULL,
},
},
{
"7 / 7 • Gateway", "Brána",
"Tip: vyšší vrstvy",
{
"Převádí mezi odlišnými architekturami nebo protokoly.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[16], "net_unit17", "net_unit17_sub",
slides, NET17_SLIDES);
}
GtkWidget *build_net_unit18_page(void) {
static const NetSlide slides[NET18_SLIDES] = {
{
"1 / 5 • Funkce", "Učení MAC adres",
"Tip: CAM tabulka = adresa → port",
{
"Switch se učí MAC adresy odesílatelů.",
"Ukládá je do CAM tabulky.",
"Rámce pak posílá jen na konkrétní port.",
NULL,
},
},
{
"2 / 5 • Metody", "Tři způsoby přepínání",
NULL,
{
"Cut-through, store-and-forward a fragment-free.",
"Liší se rychlostí a kontrolou chyb.",
NULL,
},
},
{
"3 / 5 • Cut-through", "Hned po adrese",
NULL,
{
"Čte jen adresu příjemce a hned posílá dál.",
"Nejrychlejší metoda.",
"Nevýhoda: posílá i chybné rámce.",
NULL,
},
},
{
"4 / 5 • Store-and-forward", "Celý rámec + CRC",
NULL,
{
"Přijme celý rámec a zkontroluje CRC.",
"Teprve pak rámec pošle.",
"Nejpomalejší, ale nejbezpečnější metoda.",
NULL,
},
},
{
"5 / 5 • Fragment-free", "Modifikovaný cut-through",
"Tip: prvních 64 bytů = detekce kolizí",
{
"Čte prvních 64 bytů rámce.",
"To stačí k odhalení kolizních fragmentů.",
"Kompromis mezi rychlostí a bezpečností.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[17], "net_unit18", "net_unit18_sub",
slides, NET18_SLIDES);
}
GtkWidget *build_net_unit19_page(void) {
static const NetSlide slides[NET19_SLIDES] = {
{
"1 / 7 • Princip", "Směrování paketů",
"Tip: 3. vrstva ISO/OSI – síťová",
{
"Rozhodování o dalším směru přenosu paketů do cílové sítě.",
"Probíhá na síťové vrstvě modelu ISO/OSI.",
"K rozhodování se používají směrovací algoritmy.",
NULL,
},
},
{
"2 / 7 • Adaptivní", "Dynamické algoritmy",
NULL,
{
"Reagují na změny v síti (výpadek linky, přetížení).",
"Vyžadují pravidelnou výměnu informací mezi směrovači.",
NULL,
},
},
{
"3 / 7 • Neadaptivní", "Statické algoritmy",
NULL,
{
"Nereagují na změny v síti.",
"Cesty pevně definuje správce.",
"Při výpadku části sítě může spojení spadnout.",
NULL,
},
},
{
"4 / 7 • Řízení", "Centralizované a izolované",
NULL,
{
"Centralizované: centrum počítá cesty pro všechny směrovače.",
"Výpadek centra = pád směrování; v praxi skoro nepoužívané.",
"Izolované: směrovač se rozhoduje sám z lokálních informací.",
"Izolované se používá spíš jako doplněk při přetížení.",
NULL,
},
},
{
"5 / 7 • Distribuované", "Výměna mezi směrovači",
NULL,
{
"Směrovače si vyměňují informace.",
"Každý si udržuje vlastní směrovací tabulku.",
NULL,
},
},
{
"6 / 7 • Tabulka", "Next Hop a metrika",
"Tip: nižší metrika = lepší / rychlejší trasa",
{
"Záznam: cílová síť, next hop a metrika.",
"Next hop = nejbližší soused, kterému paket předáme.",
"Metrika číselně ohodnocuje cestu.",
"Při více cestách se volí ta s nejnižší metrikou.",
NULL,
},
},
{
"7 / 7 • Distance Vector", "Příklad algoritmu",
"Tip: např. výměna tabulek každých 30 s",
{
"Směrovače znají jen své přímé sousedy.",
"Pravidelně si posílají kopie směrovacích tabulek.",
"Informace se šíří krok za krokem po celé síti.",
"Každý směrovač si spočítá nejlepší trasu do známých sítí.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[18], "net_unit19", "net_unit19_sub",
slides, NET19_SLIDES);
}
GtkWidget *build_net_unit20_page(void) {
static const NetSlide slides[NET20_SLIDES] = {
{
"1 / 7 • Router", "Síťová vrstva",
"Tip: má vlastní IP a je vidět např. pingen",
{
"Pracuje na 3. (síťové) vrstvě.",
"Segmentuje síť na podsítě nebo propojuje LAN do většího celku.",
"Umožňuje přístup na WAN (např. internet).",
"Podporuje soustavy protokolů (např. TCP/IP) a má vlastní adresu.",
NULL,
},
},
{
"2 / 7 • Bezpečnost", "Firewall na routeru",
NULL,
{
"Router s firewallem filtruje pakety.",
"Může zakázat nebo povolit určité síťové služby.",
NULL,
},
},
{
"3 / 7 • Multiprotokol", "Různé standardy",
NULL,
{
"Multiprotokolový router spojuje různé soustavy protokolů.",
"Například TCP/IP se sítěmi IPX/SPX.",
"Umí i různý síťový hardware (Ethernet ↔ Token Ring).",
"Konvertuje formát rámců i paketů.",
NULL,
},
},
{
"4 / 7 • Routing", "Směrování a tabulky",
NULL,
{
"Každému paketu hledá vhodnou cestu k cíli.",
"Zohledňuje např. okamžité zatížení sítí.",
"Používá směrovací tabulky a musí znát topologii.",
"Směrovače si tabulky vyměňují (např. broadcastem).",
NULL,
},
},
{
"5 / 7 • Broadcast", "Broadcastové domény",
NULL,
{
"Router rozděluje síť na broadcastové domény.",
"Broadcasty lze filtrovat – nešíří se na všechny porty.",
NULL,
},
},
{
"6 / 7 • Gateway", "Brána",
"Tip: pracuje až na aplikační vrstvě (i nižších)",
{
"Připojuje LAN na zcela odlišné prostředí.",
"Například mainframe nebo GSM síť.",
"Často PC s kartou/emulací terminálu nebo s modemem na WAN.",
NULL,
},
},
{
"7 / 7 • Poznámka", "Gateway vs router",
NULL,
{
"Někdy se pod pojmem brána rozumí spíše router.",
"Gateway také označuje připojení LAN na WAN / internet.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[19], "net_unit20", "net_unit20_sub",
slides, NET20_SLIDES);
}
GtkWidget *build_net_unit21_page(void) {
static const NetSlide slides[NET21_SLIDES] = {
{
"1 / 8 • Ethernet", "Síťový hardware",
NULL,
{
"Jeden ze standardů síťového hardware.",
"Dnes nejpoužívanější.",
NULL,
},
},
{
"2 / 8 • Adresy", "48bitová MAC",
"Tip: IEEE přidělí první 3 B, výrobce další 3 B",
{
"Adresa má 48 bitů (6 bytů) a je celosvětově jedinečná.",
"Je pevně v síťové kartě už od výroby.",
"Výrobci dostávají bloky adres od IEEE.",
NULL,
},
},
{
"3 / 8 • Rámce", "Typy hlaviček",
NULL,
{
"Rámec = skupina bitů na linkové vrstvě.",
"Hlavička má adresy odesílatele/příjemce a typ obsahu.",
"Typy: Ethernet II, IEEE 802.3, 802.3 SNAP, raw 802.3.",
NULL,
},
},
{
"4 / 8 • Ethernet II", "DIX + EtherType",
"Tip: EtherType > 1500 (např. IP = 0800h)",
{
"Původní DIX Ethernet.",
"Hlavička: příjemce 6 B, odesílatel 6 B, EtherType 2 B.",
"EtherType identifikuje protokol (IP, IPX…).",
NULL,
},
},
{
"5 / 8 • IEEE 802.3", "Délka místo typu",
NULL,
{
"Místo EtherType je údaj o délce (vždy ≤ 1500).",
"Uvnitř je rámec 802.2 (stejný i pro Token Ring).",
"Typ protokolu je v SAP mezi linkovou a síťovou vrstvou.",
NULL,
},
},
{
"6 / 8 • Raw 802.3", "Novell / IPX",
NULL,
{
"„Holý“ rámec 802.3 bez 802.2 (Novell).",
"Funguje jen v prostředí IPX.",
"Paket začíná dvěma byty FFFFh.",
NULL,
},
},
{
"7 / 8 • SNAP", "802.2 SNAP",
"Tip: byty 15–16 za délkou = AAAAh",
{
"Vložen do rámce 802.3.",
"Rozšiřuje identifikaci protokolu až na 5 bytů.",
NULL,
},
},
{
"8 / 8 • Velikost", "Min / max / MTU",
NULL,
{
"Max. Ethernet II: 1500 + 18 = 1518 B.",
"Min. velikost: 64 B (kolizní okénko).",
"MTU je obvyklé omezení velikosti na routerech.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[20], "net_unit21", "net_unit21_sub",
slides, NET21_SLIDES);
}
GtkWidget *build_net_unit22_page(void) {
static const NetSlide slides[NET22_SLIDES] = {
{
"1 / 8 • Paket", "Header a data",
NULL,
{
"Paket/segment: hlavička (pro partnerskou vrstvu) + data.",
"Protokol určuje strukturu a pravidla stejnolehlých vrstev.",
"Může běžet na různých platformách.",
NULL,
},
},
{
"2 / 8 • TCP/IP", "Protokoly po vrstvách",
NULL,
{
"Aplikační: aplikační protokoly.",
"Transportní: TCP, UDP.",
"Síťová: IP, ARP, RARP, ICMP, IGMP, RIP, OSPF.",
"Síťové rozhraní: Ethernet, Token Ring, ATM, PPP…",
NULL,
},
},
{
"3 / 8 • IP", "Univerzální přenos",
"Tip: nespojovaný a nespolehlivý",
{
"Jediný přenosový protokol TCP/IP nad libovolnou technologií.",
"Pracuje s virtuálními pakety – IP datagramy.",
"Stará se o směrování a přenos; velikost volí odesílatel.",
"Nezaručuje pořadí, dobu ani nepoškozené doručení.",
NULL,
},
},
{
"4 / 8 • Routing", "Routing vs forwarding",
NULL,
{
"Routing: rozhodnutí o dalším směru datagramu.",
"Forwarding: vložení do linkového rámce a odeslání.",
"Linkové adresy se mění podle konkrétní sítě.",
NULL,
},
},
{
"5 / 8 • Datagram", "Velikost a HLEN",
"Tip: Length 5 = 20 B hlavičky",
{
"Velikost: od 576 B do 64 kB.",
"Části: hlavička + data.",
"HLEN: délka hlavičky ve 32bitových slovech.",
"TOTAL LENGTH: délka celého paketu v bytech.",
NULL,
},
},
{
"6 / 8 • Hlavička", "Klíčová pole",
NULL,
{
"VERSION (IPv4 = 4), LENGTH, TOTAL LENGTH.",
"IDENTIFICATION + FLAGS + OFFSET = fragmentace.",
"TTL: čítač směrovačů proti zacyklení.",
"PROTOCOL, HEADER CHECKSUM, zdrojová/cílová IP.",
NULL,
},
},
{
"7 / 8 • PROTOCOL", "Čísla protokolů",
NULL,
{
"1 = ICMP, 2 = IGMP, 6 = TCP.",
"17 = UDP, 89 = OSPF.",
"Položka je 8bitová → max. 256 hodnot.",
NULL,
},
},
{
"8 / 8 • Fragmentace", "MTU a Ethernet",
"Tip: Ethernet MTU = 1500 B",
{
"Fragmentace, když se datagram nevejde do menšího rámce.",
"MTU udává max. velikost rámce podle hardwaru.",
"DF = nefragmentuj; MF = další fragmenty.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[21], "net_unit22", "net_unit22_sub",
slides, NET22_SLIDES);
}
GtkWidget *build_net_unit23_page(void) {
static const NetSlide slides[NET23_SLIDES] = {
{
"1 / 5 • ICMP", "Řídicí zprávy",
"Tip: síťová vrstva, ale nese se v IP datagramu",
{
"Zasílá informace o chybách a stavu přenosu.",
"ICMP paket jede přímo v IP datagramu.",
"Směrovače s ním pracují i bez transportní vrstvy.",
NULL,
},
},
{
"2 / 5 • Zprávy I", "Quench, TTL, Unreachable",
NULL,
{
"Source Quench: hrozí zahlcení – zpomal odesílání.",
"Time Exceeded: TTL kleslo na 0, paket zahozen (tracert).",
"Destination Unreachable: cíl (síť/uzel/protokol/port)",
"není dostupný.",
NULL,
},
},
{
"3 / 5 • Zprávy II", "Redirect a Echo",
NULL,
{
"Redirect: přesměruj přenos na jiný (rychlejší) router.",
"Echo Request / Echo Reply: test dostupnosti (ping).",
NULL,
},
},
{
"4 / 5 • Traceroute", "Princip TTL",
"Tip: typicky max. 30 skoků",
{
"Odešle paket s TTL = 1; první router odpoví Time Exceeded.",
"Pak TTL = 2, 3… a tak se zjišťují skoky na cestě.",
"Pokračuje, dokud paket nedorazí do cíle nebo nevyprší limit.",
NULL,
},
},
{
"5 / 5 • Shrnutí", "K čemu ICMP slouží",
NULL,
{
"Diagnostika a hlášení chyb na síťové vrstvě.",
"Základ příkazů ping a traceroute / tracert.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[22], "net_unit23", "net_unit23_sub",
slides, NET23_SLIDES);
}
GtkWidget *build_net_unit24_page(void) {
static const NetSlide slides[NET24_SLIDES] = {
{
"1 / 5 • ARP / RARP", "Převod adres",
NULL,
{
"ARP: z IP adresy na MAC (fyzickou) adresu.",
"RARP: z MAC adresy na IP adresu.",
NULL,
},
},
{
"2 / 5 • Způsoby", "Jak zjistit MAC",
NULL,
{
"Tabulkový převod: ruční správa (malé sítě).",
"Výpočet: funkce, kde MAC plyne z IP.",
"Dotaz a odpověď: dynamické zjišťování (nejčastější).",
NULL,
},
},
{
"3 / 5 • Mechanismus", "Broadcast a unicast",
"Tip: „Kdo má IP x.x.x.x?“",
{
"ARP využívá broadcast v Ethernetu.",
"Odpoví jen uzel s danou IP.",
"Odpověď jde unicastem a obsahuje MAC adresu.",
NULL,
},
},
{
"4 / 5 • Cache", "Dočasná paměť",
"Tip: zobrazení příkazem arp -a",
{
"Výsledky se ukládají do ARP cache.",
"Dotazy se tak nemusí stále opakovat.",
"Položky: dynamické (učené) nebo statické (ruční).",
NULL,
},
},
{
"5 / 5 • Shrnutí", "K čemu ARP slouží",
NULL,
{
"Propojuje síťovou adresu (IP) s linkovou (MAC).",
"Bez ARP by IP datagram nešel vložit do Ethernet rámce.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[23], "net_unit24", "net_unit24_sub",
slides, NET24_SLIDES);
}
GtkWidget *build_net_unit25_page(void) {
static const NetSlide slides[NET25_SLIDES] = {
{
"1 / 6 • TCP vs UDP", "Základní rozdíly",
NULL,
{
"TCP: spolehlivý a spojovaný přenos.",
"Potvrzování, kontrola pořadí a řízení toku.",
"UDP: nespolehlivý a nespojovaný.",
"Minimální režie – neřeší potvrzení ani pořadí.",
NULL,
},
},
{
"2 / 6 • Porty", "Multiplex a demultiplex",
NULL,
{
"Porty rozlišují aplikace (procesy) na jednom uzlu.",
"Multiplex: sběr dat od aplikací do segmentů/datagramů.",
"Demultiplex: doručení příchozích dat správné aplikaci",
"podle čísla portu.",
NULL,
},
},
{
"3 / 6 • TCP", "Spojení a vlastnosti",
"Tip: three-way handshake",
{
"Navázání spojení: třícestné podání ruky.",
"Streamově orientovaný a full duplex.",
"Jen unicast – bez multicastu a broadcastu.",
NULL,
},
},
{
"4 / 6 • Nevýhody TCP", "Režie a real-time",
NULL,
{
"Větší režie: hlavička 20 B (UDP má 8 B).",
"Nevhodný pro real-time média: ztráta segmentu",
"zastaví proud a čeká se na znovudoručení.",
"Bez multihomingu – výpadek rozhraní shodí spojení.",
NULL,
},
},
{
"5 / 6 • Alternativy", "SCTP a DCCP",
NULL,
{
"SCTP: multihoming a multistreaming (až 64k proudů).",
"DCCP: datagramy s řízením zahlcení",
"(streaming, IP telefonie).",
NULL,
},
},
{
"6 / 6 • Shrnutí", "Kdy co použít",
NULL,
{
"TCP: spolehlivá data (web, pošta, soubory).",
"UDP: rychlost a nízká režie (DNS, hry, real-time).",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[24], "net_unit25", "net_unit25_sub",
slides, NET25_SLIDES);
}
GtkWidget *build_net_unit26_page(void) {
static const NetSlide slides[NET26_SLIDES] = {
{
"1 / 7 • Úvod", "Aplikační protokoly",
NULL,
{
"Na uzlu běží více síťových aplikací současně.",
"Běžící aplikace = v operační paměti (1+ procesů).",
"Pracují podle pravidel – protokolů aplikační vrstvy.",
"Data posílají po síti přes TCP nebo UDP.",
NULL,
},
},
{
"2 / 7 • Porty", "Procesy a porty",
NULL,
{
"Port v TCP/UDP říká, které aplikaci data patří.",
"Jeden proces může používat více portů.",
"Dva procesy nesmí používat stejný port.",
NULL,
},
},
{
"3 / 7 • Rozsahy", "Well-known, registrované, dynamické",
"Tip: IANA",
{
"Well-known: 0–1023 – vyhrazené službám (norma IANA).",
"Registrované: 1024–49151 – IANA jen registruje použití.",
"Dynamické/privátní: 49152–65535 – volně k použití.",
NULL,
},
},
{
"4 / 7 • Spojení", "Pětice hodnot",
NULL,
{
"Aplikační spojení určuje pětice:",
"(transport, IP1, port1, IP2, port2).",
"Klient osloví server na well-known portu.",
NULL,
},
},
{
"5 / 7 • Více spojení", "Stejný server, různí klienti",
NULL,
{
"Na jeden uzel (např. web server) může být",
"více aplikačních spojení z různých klientů.",
"Rozlišují je IP a porty klientů (i transport).",
NULL,
},
},
{
"6 / 7 • Porty I", "Časté well-known služby",
NULL,
{
"20/21 FTP, 22 SSH, 23 Telnet, 25 SMTP, 53 DNS.",
"67/68 DHCP, 80 HTTP, 110 POP3, 143 IMAP.",
"123 NTP, 161 SNMP, 389 LDAP, 443 HTTPS.",
NULL,
},
},
{
"7 / 7 • Porty II", "Zabezpečené a registrované",
NULL,
{
"587 SMTPS, 636 LDAPS, 993 IMAPS, 995 POP3S.",
"Registrované: 3306 MySQL, 3389 RDP, 5900 VNC.",
"Dynamické porty: 49152–65535.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[25], "net_unit26", "net_unit26_sub",
slides, NET26_SLIDES);
}
GtkWidget *build_net_unit27_page(void) {
static const NetSlide slides[NET27_SLIDES] = {
{
"1 / 8 • Úvod", "Bezdrátové sítě",
NULL,
{
"Patří sem hlavně: družicové, mikrovlnné a optické spoje.",
"Dále Wi-Fi (LAN), WiMAX/LTE (MAN/WAN) a další.",
NULL,
},
},
{
"2 / 8 • Družice", "Geostacionární spoje",
NULL,
{
"Geostacionární družice: ~36 000 km, stále nad stejným bodem.",
"Pasivní odrážejí; aktivní mají transpondéry (převod + zisk).",
"C-band ~6/4 GHz; KU-band 12–14 GHz (menší antény).",
"Nevýhoda: zpoždění ~250–300 ms (RTT až ~600 ms).",
NULL,
},
},
{
"3 / 8 • VSAT", "Přístup a topologie",
NULL,
{
"Bod–bod, broadcast (TV) i multiple access.",
"VSAT: terminály + centrální hub.",
"Komunikace jen terminál ↔ hub (ne přímo mezi terminály).",
NULL,
},
},
{
"4 / 8 • Mikrovlny", "Pozemní spoje",
"Tip: přímá viditelnost",
{
"Frekvence 1–12 GHz, směrování parabolou, malý rozptyl.",
"Dosah typicky do ~50 km; retranslační stanice.",
"Troposférické spoje: odraz ve ~16 km, dosah až ~500 km.",
NULL,
},
},
{
"5 / 8 • Wi-Fi pojmy", "AP, BSS, ESS",
NULL,
{
"AP = přístupový bod; STA komunikují přes AP (ne přímo).",
"BSS = stanice v buňce BSA; ESS = více buněk přes DS.",
"Roaming při překrytí; ad-hoc = P2P bez AP; hotspot = Wi-Fi.",
"ESSID identifikuje síť při přístupu k AP.",
NULL,
},
},
{
"6 / 8 • Standardy", "802.11 a … ax",
NULL,
{
"b: 11 Mb/s, 2,4 GHz; a/g: 54 Mb/s; n: MIMO, až 600 Mb/s.",
"ac (Wi-Fi 5): 256-QAM, široké kanály; ax (Wi-Fi 6): OFDMA.",
"OFDM: mnoho ortogonálních subnosných v kanálu.",
NULL,
},
},
{
"7 / 8 • Zabezpečení", "WEP → WPA3",
NULL,
{
"WEP: RC4, krátký IV – prolomeno (2001), nepoužívat.",
"WPA: TKIP; WPA2: AES (doporučený základ).",
"WPA3: SAE místo PSK, silnější ochrana hesla.",
"802.1X/EAP: ověření klienta přes AP (RADIUS).",
NULL,
},
},
{
"8 / 8 • Shrnutí", "Dosahy a další",
NULL,
{
"PAN <10 m (Bluetooth); LAN = Wi-Fi; MAN = WiMAX.",
"WAN/mobilita: 802.16e, LTE; licencovaná pásma = méně rušení.",
"Používej WPA2/WPA3 + AES, ne WEP.",
NULL,
},
},
};
return build_net_unit_page(&net_lessons[26], "net_unit27", "net_unit27_sub",
slides, NET27_SLIDES);
}
/* Solutions below are the canonical "largest subnet first, in order A–D"
* allocation. Scenario 3 does not fit into a /24 as written, which is why
* its "solution" explains that instead. */
const NetTask net_tasks[] = {
{
"1.) Síť má adresu 10.0.0.0/24. Rozdělte ji do podsítí s následujícími "
"požadavky:\n\n"
"Podsíť A: 60 uzlů\nPodsíť B: 30 uzlů\nPodsíť C: 14 uzlů\n"
"Podsíť D: 7 uzlů",
"A: 10.0.0.0/26 síť 10.0.0.0 uzly 10.0.0.1–10.0.0.62 "
"broadcast 10.0.0.63\n"
"B: 10.0.0.64/27 síť 10.0.0.64 uzly 10.0.0.65–10.0.0.94 "
"broadcast 10.0.0.95\n"
"C: 10.0.0.96/28 síť 10.0.0.96 uzly 10.0.0.97–10.0.0.110 "
"broadcast 10.0.0.111\n"
"D: 10.0.0.112/28 síť 10.0.0.112 uzly 10.0.0.113–10.0.0.126 "
"broadcast 10.0.0.127",
},
{
"2.) Síť má adresu 172.16.0.0/16. Rozdělte ji do podsítí s "
"následujícími požadavky:\n\n"
"Podsíť A: 500 uzlů\nPodsíť B: 200 uzlů\nPodsíť C: 100 uzlů\n"
"Podsíť D: 50 uzlů",
"A: 172.16.0.0/23 síť 172.16.0.0 uzly 172.16.0.1–172.16.1.254 "
"broadcast 172.16.1.255\n"
"B: 172.16.2.0/24 síť 172.16.2.0 uzly 172.16.2.1–172.16.2.254 "
"broadcast 172.16.2.255\n"
"C: 172.16.3.0/25 síť 172.16.3.0 uzly 172.16.3.1–172.16.3.126 "
"broadcast 172.16.3.127\n"
"D: 172.16.3.128/26 síť 172.16.3.128 uzly 172.16.3.129–172.16.3.190 "
"broadcast 172.16.3.191",
},
{
"3.) Síť má adresu 192.168.10.0/24. Rozdělte ji do podsítí s "
"následujícími požadavky:\n\n"
"Podsíť A: 120 uzlů\nPodsíť B: 70 uzlů\nPodsíť C: 35 uzlů\n"
"Podsíť D: 15 uzlů",
"Do sítě /24 se tyto požadavky nevejdou: A i B potřebují /25 "
"(2 × 128 = 256 adres), na C a D už nezbude žádný blok. "
"Při zachování velikostí by bylo nutné větší síť (např. /23).",
},
{
"4.) Síť má adresu 192.168.2.0/25. Rozdělte ji do podsítí s "
"následujícími požadavky:\n\n"
"Podsíť A: 50 uzlů\nPodsíť B: 25 uzlů\nPodsíť C: 12 uzlů\n"
"Podsíť D: 5 uzlů",
"A: 192.168.2.0/26 síť 192.168.2.0 uzly 192.168.2.1–192.168.2.62 "
"broadcast 192.168.2.63\n"
"B: 192.168.2.64/27 síť 192.168.2.64 "
"uzly 192.168.2.65–192.168.2.94 broadcast 192.168.2.95\n"
"C: 192.168.2.96/28 síť 192.168.2.96 "
"uzly 192.168.2.97–192.168.2.110 broadcast 192.168.2.111\n"
"D: 192.168.2.112/28 síť 192.168.2.112 "
"uzly 192.168.2.113–192.168.2.126 broadcast 192.168.2.127",
},
};
/* Interactive subnet calculator for the practice sheet: the student
* chooses a prefix and types the network address, broadcast and the
* usable host range. */
const NetAns net_ans[4][4] = {
{ /* 10.0.0.0/24 */
{26, "10.0.0.0", "10.0.0.63", "10.0.0.1", "10.0.0.62"},
{27, "10.0.0.64", "10.0.0.95", "10.0.0.65", "10.0.0.94"},
{28, "10.0.0.96", "10.0.0.111", "10.0.0.97", "10.0.0.110"},
{28, "10.0.0.112", "10.0.0.127", "10.0.0.113", "10.0.0.126"},
},
{ /* 172.16.0.0/16 */
{23, "172.16.0.0", "172.16.1.255", "172.16.0.1", "172.16.1.254"},
{24, "172.16.2.0", "172.16.2.255", "172.16.2.1", "172.16.2.254"},
{25, "172.16.3.0", "172.16.3.127", "172.16.3.1", "172.16.3.126"},
{26, "172.16.3.128", "172.16.3.191", "172.16.3.129", "172.16.3.190"},
},
{ /* does not fit into a /24 */
{-1, NULL, NULL, NULL, NULL},
{-1, NULL, NULL, NULL, NULL},
{-1, NULL, NULL, NULL, NULL},
{-1, NULL, NULL, NULL, NULL},
},
{ /* 192.168.2.0/25 */
{26, "192.168.2.0", "192.168.2.63", "192.168.2.1", "192.168.2.62"},
{27, "192.168.2.64", "192.168.2.95", "192.168.2.65", "192.168.2.94"},
{28, "192.168.2.96", "192.168.2.111", "192.168.2.97", "192.168.2.110"},
{28, "192.168.2.112", "192.168.2.127", "192.168.2.113", "192.168.2.126"},
},
};
GtkWidget *net_qz_combo(void) {
GtkWidget *c = gtk_combo_box_text_new();
for (int p = 8; p <= 30; p++) {
char buf[8];
g_snprintf(buf, sizeof(buf), "/%d", p);
gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(c), NULL, buf);
}
gtk_combo_box_set_active(GTK_COMBO_BOX(c), -1);
return c;
}
void net_qz_set_prefix(GtkComboBoxText *c, int pfx) {
if (pfx >= 8 && pfx <= 30)
gtk_combo_box_set_active(GTK_COMBO_BOX(c), pfx - 8);
else
gtk_combo_box_set_active(GTK_COMBO_BOX(c), -1);
}
int net_qz_prefix(GtkComboBoxText *c) {
gchar *txt = gtk_combo_box_text_get_active_text(c);
int p = txt ? atoi(txt + (txt[0] == '/' ? 1 : 0)) : -1;
g_free(txt);
return p;
}
/* Case- and space-insensitive comparison of typed address answers. */
gboolean net_txt_eq(const char *a, const char *b) {
const char *x, *y;
if (!a || !b)
return a == b;
x = a;
y = b;
while (*x && *y) {
while (*x == ' ' || *x == '\t')
x++;
while (*y == ' ' || *y == '\t')
y++;
if (g_ascii_tolower((guchar)*x) != g_ascii_tolower((guchar)*y))
return FALSE;
if (*x)
x++;
if (*y)
y++;
}
while (*x == ' ' || *x == '\t')
x++;
while (*y == ' ' || *y == '\t')
y++;
return *x == '\0' && *y == '\0';
}
gboolean net_qz_entry_ok(GtkWidget *entry, const char *want) {
const gchar *got = gtk_editable_get_text(GTK_EDITABLE(entry));
return got && net_txt_eq(got, want);
}
static gboolean net_u1_task_ok[4];
void net_qz_check(GtkButton *button, gpointer data) {
NetQz *q = data;
int ok = 0;
(void)button;
if (q->infeasible) {
set_feedback(q->feed, FALSE,
"Toto zadání se do sítě /24 nevejde – vyzkoušej "
"„Ukázat řešení“ a přečti si proč.");
return;
}
for (int i = 0; i < 4; i++) {
const NetAns *a = &net_ans[q->id][i];
gboolean p_ok = a->pfx > 0 &&
net_qz_prefix(GTK_COMBO_BOX_TEXT(q->combo[i])) == a->pfx;
gboolean net_ok = net_qz_entry_ok(q->net[i], a->net);
gboolean bc_ok = net_qz_entry_ok(q->bcast[i], a->bcast);
gboolean lo_ok = net_qz_entry_ok(q->lo[i], a->lo);
gboolean hi_ok = net_qz_entry_ok(q->hi[i], a->hi);
answer_mark(q->combo[i], p_ok);
answer_mark(q->net[i], net_ok);
answer_mark(q->bcast[i], bc_ok);
answer_mark(q->lo[i], lo_ok);
answer_mark(q->hi[i], hi_ok);
if (p_ok && net_ok && bc_ok && lo_ok && hi_ok)
ok++;
}
if (ok == 4) {
set_feedback(q->feed, TRUE, tr("feedback_ok"));
net_u1_task_ok[q->id] = TRUE;
if (net_u1_task_ok[0] && net_u1_task_ok[1] && net_u1_task_ok[2] &&
net_u1_task_ok[3])
mark_net_done(0);
} else {
set_feedback(q->feed, FALSE, tr("feedback_retry"));
}
}
void net_qz_fill(GtkButton *button, gpointer data) {
NetQz *q = data;
(void)button;
for (int i = 0; i < 4; i++) {
const NetAns *a = &net_ans[q->id][i];
if (a->pfx <= 0)
continue;
net_qz_set_prefix(GTK_COMBO_BOX_TEXT(q->combo[i]), a->pfx);
gtk_editable_set_text(GTK_EDITABLE(q->net[i]), a->net);
gtk_editable_set_text(GTK_EDITABLE(q->bcast[i]), a->bcast);
gtk_editable_set_text(GTK_EDITABLE(q->lo[i]), a->lo);
gtk_editable_set_text(GTK_EDITABLE(q->hi[i]), a->hi);
}
if (q->note)
gtk_widget_set_visible(q->note, TRUE);
if (q->infeasible) {
net_u1_task_ok[q->id] = TRUE;
if (net_u1_task_ok[0] && net_u1_task_ok[1] && net_u1_task_ok[2] &&
net_u1_task_ok[3])
mark_net_done(0);
}
}
void net_qz_header(GtkWidget *box, const char *text) {
GtkWidget *l = gtk_label_new(text);
gtk_widget_add_css_class(l, "meaning");
gtk_widget_set_halign(l, GTK_ALIGN_START);
gtk_box_append(GTK_BOX(box), l);
}
GtkWidget *net_qz_make_entry(void) {
GtkWidget *e = gtk_entry_new();
gtk_widget_set_hexpand(e, TRUE);
gtk_editable_set_width_chars(GTK_EDITABLE(e), 15);
return e;
}
GtkWidget *build_net_exercise_page(void) {
GtkWidget *page;
GtkWidget *scroll;
GtkWidget *body;
page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_margin_start(page, 32);
gtk_widget_set_margin_end(page, 32);
gtk_widget_set_margin_top(page, 24);
gtk_widget_set_margin_bottom(page, 24);
gtk_box_append(GTK_BOX(page),
top_bar("netunit1", "net_ex_title", NULL));
scroll = gtk_scrolled_window_new();
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_widget_set_vexpand(scroll, TRUE);
gtk_widget_set_margin_top(scroll, 12);
gtk_box_append(GTK_BOX(page), scroll);
body = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scroll), body);
net_heading(body,
"Zadání pro výpočet IP adres – k procvičení");
net_paragraph(body,
"Určete pro každou podsíť:\n"
"• Maska podsítě (prefix)\n"
"• Rozsah IP adres podsítě\n"
"• Rozsah IP adres pro uzly\n"
"• Síťovou adresu\n"
"• Broadcast adresu");
for (guint t = 0; t < G_N_ELEMENTS(net_tasks); t++) {
GtkWidget *task = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
GtkWidget *table;
GtkWidget *btns;
GtkWidget *reveal;
GtkWidget *check;
GtkWidget *sol;
NetQz *q = g_new0(NetQz, 1);
q->infeasible = (t == 2);
q->id = (int)t;
gtk_widget_set_margin_top(task, 10);
gtk_box_append(GTK_BOX(body), task);
net_paragraph(task, net_tasks[t].prompt);
if (q->infeasible) {
net_qz_header(task, net_tasks[t].solution);
} else {
static const char *cols[] = {"Prefix", "Síťová adresa",
"Broadcast", "Uzly od", "Uzly do"};
table = gtk_grid_new();
gtk_grid_set_row_spacing(GTK_GRID(table), 6);
gtk_grid_set_column_spacing(GTK_GRID(table), 8);
gtk_widget_set_margin_top(table, 6);
gtk_box_append(GTK_BOX(task), table);
for (guint c = 1; c < 6; c++) {
GtkWidget *h = gtk_label_new(cols[c - 1]);
gtk_widget_add_css_class(h, "meaning");
gtk_grid_attach(GTK_GRID(table), h, (int)c, 0, 1, 1);
}
for (int i = 0; i < 4; i++) {
char letter[8];
GtkWidget *lab = gtk_label_new(NULL);
int row = i + 1;
g_snprintf(letter, sizeof(letter), "%c", 'A' + i);
gtk_label_set_text(GTK_LABEL(lab), letter);
gtk_widget_add_css_class(lab, "ex-prompt");
gtk_grid_attach(GTK_GRID(table), lab, 0, row, 1, 1);
q->combo[i] = net_qz_combo();
gtk_grid_attach(GTK_GRID(table), q->combo[i], 1, row, 1, 1);
q->net[i] = net_qz_make_entry();
gtk_grid_attach(GTK_GRID(table), q->net[i], 2, row, 1, 1);
q->bcast[i] = net_qz_make_entry();
gtk_grid_attach(GTK_GRID(table), q->bcast[i], 3, row, 1, 1);
q->lo[i] = net_qz_make_entry();
gtk_grid_attach(GTK_GRID(table), q->lo[i], 4, row, 1, 1);
q->hi[i] = net_qz_make_entry();
gtk_grid_attach(GTK_GRID(table), q->hi[i], 5, row, 1, 1);
}
}
btns = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
gtk_box_append(GTK_BOX(task), btns);
if (!q->infeasible) {
check = gtk_button_new();
i18n_bind(check, "check", 1);
gtk_widget_add_css_class(check, "pill");
gtk_widget_set_halign(check, GTK_ALIGN_START);
gtk_box_append(GTK_BOX(btns), check);
g_signal_connect(check, "clicked", G_CALLBACK(net_qz_check), q);
}
reveal = gtk_button_new();
i18n_bind(reveal, "net_solution", 1);
gtk_widget_add_css_class(reveal, "pill");
gtk_widget_set_halign(reveal, GTK_ALIGN_START);
gtk_box_append(GTK_BOX(btns), reveal);
g_signal_connect(reveal, "clicked", G_CALLBACK(net_qz_fill), q);
q->feed = gtk_label_new("");
gtk_widget_set_halign(q->feed, GTK_ALIGN_START);
gtk_box_append(GTK_BOX(task), q->feed);
sol = gtk_label_new(net_tasks[t].solution);
gtk_widget_set_halign(sol, GTK_ALIGN_START);
gtk_label_set_xalign(GTK_LABEL(sol), 0.0);
gtk_label_set_wrap(GTK_LABEL(sol), TRUE);
gtk_widget_set_margin_start(sol, 8);
gtk_widget_add_css_class(sol, "meaning");
gtk_widget_set_visible(sol, FALSE);
gtk_box_append(GTK_BOX(task), sol);
q->note = sol;
}
return page;
}
/* ---- Units 2–10: shared multiple-choice quizzes -------------------- */
void net_mcq_check(GtkButton *button, gpointer data) {
NetMcqCtx *ctx = data;
int ok = 0;
(void)button;
for (int i = 0; i < ctx->n; i++) {
int active = -1;
for (int o = 0; o < ctx->n_opts; o++) {
GtkToggleButton *tb = ctx->toggles[i * ctx->n_opts + o];
gtk_widget_remove_css_class(GTK_WIDGET(tb), "ok");
gtk_widget_remove_css_class(GTK_WIDGET(tb), "wrong");
if (gtk_toggle_button_get_active(tb))
active = o;
}
if (active == ctx->qs[i].correct) {
ok++;
gtk_widget_add_css_class(
GTK_WIDGET(ctx->toggles[i * ctx->n_opts + active]), "ok");
} else if (active >= 0) {
gtk_widget_add_css_class(
GTK_WIDGET(ctx->toggles[i * ctx->n_opts + active]), "wrong");
}
if (ctx->hints && ctx->hints[i])
gtk_widget_set_visible(ctx->hints[i], TRUE);
}
if (ok == ctx->n) {
set_feedback(ctx->feedback, TRUE, tr("feedback_ok"));
mark_net_done(ctx->lesson_id);
} else {
set_feedback(ctx->feedback, FALSE, tr("feedback_retry_short"));
}
}
GtkWidget *build_net_mcq_page(int lesson_id, const char *back_page,
const char *title_key, const char *heading_key,
const ChoiceQ *qs, const char **hints, int n) {
GtkWidget *page;
GtkWidget *scroll;
GtkWidget *body;
GtkWidget *check;
GtkWidget *btns;
GtkWidget *head;
GtkWidget *intro;
NetMcqCtx *ctx = g_new0(NetMcqCtx, 1);
int n_opts = qs[0].n_options;
page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_margin_start(page, 32);
gtk_widget_set_margin_end(page, 32);
gtk_widget_set_margin_top(page, 24);
gtk_widget_set_margin_bottom(page, 24);
gtk_box_append(GTK_BOX(page), top_bar(back_page, title_key, NULL));
scroll = gtk_scrolled_window_new();
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_widget_set_vexpand(scroll, TRUE);
gtk_widget_set_margin_top(scroll, 12);
gtk_box_append(GTK_BOX(page), scroll);
body = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scroll), body);
head = gtk_label_new(NULL);
i18n_bind(head, heading_key, 0);
gtk_widget_set_halign(head, GTK_ALIGN_START);
gtk_label_set_wrap(GTK_LABEL(head), TRUE);
gtk_widget_set_margin_top(head, 6);
gtk_widget_add_css_class(head, "ex-sub");
gtk_box_append(GTK_BOX(body), head);
intro = gtk_label_new(NULL);
i18n_bind(intro, "net_quiz_intro", 0);
gtk_widget_set_halign(intro, GTK_ALIGN_START);
gtk_label_set_wrap(GTK_LABEL(intro), TRUE);
gtk_widget_add_css_class(intro, "ex-prompt");
gtk_box_append(GTK_BOX(body), intro);
ctx->qs = qs;
ctx->n = n;
ctx->n_opts = n_opts;
ctx->lesson_id = lesson_id;
ctx->toggles = g_new0(GtkToggleButton *, n * n_opts);
ctx->hints = g_new0(GtkWidget *, n);
for (int i = 0; i < n; i++) {
GtkWidget *prompt;
GtkWidget *row;
GtkToggleButton *first = NULL;
char *qtext;
qtext = g_strdup_printf("%d.) %s", i + 1, qs[i].prompt);
prompt = gtk_label_new(qtext);
g_free(qtext);
gtk_widget_set_halign(prompt, GTK_ALIGN_START);
gtk_label_set_wrap(GTK_LABEL(prompt), TRUE);
gtk_widget_add_css_class(prompt, "ex-prompt");
gtk_widget_set_margin_top(prompt, 8);
gtk_box_append(GTK_BOX(body), prompt);
row = gtk_flow_box_new();
gtk_flow_box_set_selection_mode(GTK_FLOW_BOX(row), GTK_SELECTION_NONE);
gtk_flow_box_set_min_children_per_line(GTK_FLOW_BOX(row), n_opts);
gtk_flow_box_set_max_children_per_line(GTK_FLOW_BOX(row), n_opts);
gtk_widget_set_halign(row, GTK_ALIGN_START);
gtk_box_append(GTK_BOX(body), row);
for (int o = 0; o < n_opts; o++) {
GtkWidget *tb = gtk_toggle_button_new_with_label(qs[i].options[o]);
gtk_widget_add_css_class(tb, "pill");
gtk_toggle_button_set_group(GTK_TOGGLE_BUTTON(tb), first);
if (!first)
first = GTK_TOGGLE_BUTTON(tb);
gtk_flow_box_append(GTK_FLOW_BOX(row), tb);
ctx->toggles[i * n_opts + o] = GTK_TOGGLE_BUTTON(tb);
}
ctx->hints[i] = meaning_add(body, hints[i]);
}
btns = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
gtk_widget_set_margin_top(btns, 12);
gtk_box_append(GTK_BOX(body), btns);
check = gtk_button_new();
i18n_bind(check, "check", 1);
gtk_widget_add_css_class(check, "pill");
gtk_widget_set_halign(check, GTK_ALIGN_START);
gtk_box_append(GTK_BOX(btns), check);
g_signal_connect(check, "clicked", G_CALLBACK(net_mcq_check), ctx);
ctx->feedback = gtk_label_new("");
gtk_widget_set_halign(ctx->feedback, GTK_ALIGN_START);
gtk_box_append(GTK_BOX(body), ctx->feedback);
return page;
}
const ChoiceQ net2_qs[] = {
{"Kolik bitů má jeden byte?",
{"4", "8", "16", "32"}, 4, 1},
{"Kolik různých hodnot nabývá jeden byte?",
{"128", "255", "256", "512"}, 4, 2},
{"Co je trvalé propojení sítě?",
{"Modem", "Wi‑Fi", "Kabely", "Bluetooth"}, 4, 2},
{"Co označuje zkratka WAN?",
{"Lokální síť v budově", "Městskou síť",
"Rozsáhlou síť (státy, kontinenty)", "Bezdrátovou síť"}, 4, 2},
{"Co je topologie sítě?",
{"Norma pro zpracování dat", "Způsob propojení uzlů",
"Název serveru", "Rychlost přenosu"}, 4, 1},
{"Architektura sítě je:",
{"Jen topologie", "Jen standard", "Topologie + standard",
"Pouze typ kabelu"}, 4, 2},
{"Peer‑to‑peer síť znamená:",
{"Síť s jedním výkonným serverem",
"Síť bez serverů – stanice sdílejí data",
"Jen internetovou síť", "Síť pouze s tiskárnami"}, 4, 1},
{"Server v síti je:",
{"Jednoduchá stanice pro uživatele",
"Nadřazený uzel poskytující služby",
"Jen aktivní prvek kabeláže", "Dočasné Wi‑Fi připojení"}, 4, 1},
};
const char *net2_hints[] = {
"1 B = 8 b",
"2⁸ = 256 hodnot (0–255)",
"Kabely – síť zůstává připojená i po přenosu",
"WAN = Wide Area Network, např. internet",
"Např. hvězda, kruh, sběrnice",
"Architektura = topologie + standard",
"Bez centrálního serveru – stanice si sdílejí data a tiskárny",
"Server řídí a poskytuje služby, má vyšší výkon",
};
GtkWidget *build_net_unit2_exercise_page(void) {
return build_net_mcq_page(1, "netunit2", "net_ex2_title", "net_quiz2_head",
net2_qs, net2_hints,
(int)G_N_ELEMENTS(net2_qs));
}
const ChoiceQ net3_qs[] = {
{"Co typicky dělají servery v síti?",
{"Jen tisknou dokumenty", "Ověřují uživatele a povolují přístup",
"Nahrazují kabely", "Slouží jen jako Wi‑Fi"}, 4, 1},
{"Fileserver je:",
{"Tiskový server", "Poštovní server", "Souborový server",
"Databázový server"}, 4, 2},
{"Centralizovaný server znamená:",
{"Více serverů v síti", "Jeden server – výpadek = nedostupnost služby",
"Server jen pro tisk", "Cloud bez internetu"}, 4, 1},
{"Distribuovaný model serverů nabízí hlavně:",
{"Nižší spolehlivost", "Vyšší spolehlivost a rychlost",
"Jen levnější kabely", "Odstranění uživatelů"}, 4, 1},
{"Nevyhrazený server:",
{"Slouží jen síťovým službám", "Slouží i jako pracovní stanice",
"Je vždy mainframe", "Nemůže ověřovat uživatele"}, 4, 1},
{"Vyhrazený server je určen:",
{"Jen jako stanice uživatele", "Jen pro síťové služby",
"Jen pro Bluetooth", "Jen pro dočasné Wi‑Fi"}, 4, 1},
{"Mainframe se typicky používá:",
{"Jen v domácnostech", "V bankách a státní správě",
"Jen pro streamování hudby", "Jen jako tiskárna"}, 4, 1},
{"Cloud a SaaS znamenají především:",
{"Lokální síť bez internetu",
"Vzdálené servery a software jako služba online",
"Jen jeden kabel v budově", "Peer‑to‑peer bez serverů"}, 4, 1},
};
const char *net3_hints[] = {
"Ověřují uživatele a povolují přístup ke službám",
"Fileserver = souborový server",
"Jeden server – při výpadku je služba nedostupná",
"Více serverů, každý obsluhuje část – vyšší spolehlivost",
"Slouží zároveň i jako pracovní stanice",
"Jen síťové služby – vysoký výkon a bezpečnost, často v racku",
"Obří sálové počítače (IBM, Siemens) pro banky a státní správu",
"SaaS = software jako služba, přístup online z libovolného zařízení",
};
GtkWidget *build_net_unit3_exercise_page(void) {
return build_net_mcq_page(2, "netunit3", "net_ex3_title", "net_quiz3_head",
net3_qs, net3_hints,
(int)G_N_ELEMENTS(net3_qs));
}
const ChoiceQ net4_qs[] = {
{"Paralelní přenos znamená:",
{"Bit po bitu po jednom vodiči",
"Více bitů současně po více vodičích",
"Jen Wi‑Fi bez kabelů", "Jen cloudové ukládání"}, 4, 1},
{"Hlavní problém paralelního přenosu při delších kabelech je:",
{"Absence serveru", "Přeslechy (rušení)", "Chybějící SaaS",
"Peer‑to‑peer režim"}, 4, 1},
{"Sériový přenos je oproti paralelnímu celkově:",
{"Vždy pomalejší", "Rychlejší díky vyšším frekvencím a délkám",
"Jen pro tiskárny", "Bez jakéhokoli kabelu"}, 4, 1},
{"V asynchronním přenosu start-bit má hodnotu:",
{"1", "0", "8", "255"}, 4, 1},
{"Synchronní přenos je řízen:",
{"Jen stop-bitem", "Společným hodinovým signálem",
"Jen paritou", "Jen checksumem"}, 4, 1},
{"Nejslabší metoda zabezpečení z uvedených je:",
{"CRC", "Checksum", "Parita", "Mainframe"}, 4, 2},
{"Checksum spočívá v:",
{"Přidání start-bitu", "Součtu znaků jako dvojkových čísel",
"Jen Wi‑Fi šifrování", "Výměně kabelů"}, 4, 1},
{"CRC (cyklické kódy) je z uvedených metod:",
{"Nejslabší", "Stejně slabá jako parita", "Nejbezpečnější",
"Jen pro paralelní přenos"}, 4, 2},
};
const char *net4_hints[] = {
"Více bitů najednou po více vodičích; problém jsou přeslechy",
"Přeslechy vznikají při delších kabelech a vysokých frekvencích",
"Bit po bitu po jednom vodiči – vyšší frekvence i délky",
"Start-bit (0) synchronizuje, Stop-bit (1) ukončuje znak",
"Řízeno společným hodinovým signálem a přesným časováním",
"Nejslabší – přidá bit pro sudý/lichý počet jedniček",
"Součet znaků jako dvojkových čísel",
"Nejbezpečnější – počítá se z jednotlivých bitů v bloku",
};
GtkWidget *build_net_unit4_exercise_page(void) {
return build_net_mcq_page(3, "netunit4", "net_ex4_title", "net_quiz4_head",
net4_qs, net4_hints,
(int)G_N_ELEMENTS(net4_qs));
}
const ChoiceQ net5_qs[] = {
{"Digitální signál nabývá:",
{"Libovolných spojitých hodnot", "Diskrétních hodnot 0 a 1",
"Jen frekvence FM", "Jen šířky pásma"}, 4, 1},
{"Frekvence f je:",
{"Stejná jako amplituda", "f = 1/T", "Jen fázový posun",
"Počet bitů v QPSK"}, 4, 1},
{"AM, FM a PM jsou:",
{"Typy kabelů", "Základní typy modulace", "Jen CRC metody",
"Typy serverů"}, 4, 1},
{"QPSK přenáší v jednom prvku:",
{"1 bit", "2 bity", "8 bitů", "256 bitů"}, 4, 1},
{"256-QAM přenáší v jednom prvku:",
{"2 bity", "4 bity", "8 bitů", "16 bitů"}, 4, 2},
{"Modulační rychlost se udává v:",
{"Jen bit/s", "Baud (Bd/s)", "Jen metrech", "Jen hertzech amplitudy"}, 4, 1},
{"Přenosová rychlost vyjadřuje:",
{"Počet změn signálu za sekundu", "Velikost přenesené informace [bit/s]",
"Jen fázový posun", "Jen periodu T"}, 4, 1},
{"Šířka pásma určuje:",
{"Jen barvu kabelu", "Maximální možnou přenosovou rychlost",
"Jen počet serverů", "Jen start-bit"}, 4, 1},
};
const char *net5_hints[] = {
"Analogový je spojitý, digitální má diskrétní hodnoty 0 a 1",
"Frekvence f = 1/T, kde T je perioda",
"AM mění amplitudu, FM frekvenci, PM fázi",
"QPSK nese 2 bity v prvku, 256-QAM nese 8 bitů",
"QPSK nese 2 bity v prvku, 256-QAM nese 8 bitů",
"Modulační rychlost = počet změn signálu za sekundu [Bd/s]",
"Přenosová rychlost = množství informace za sekundu [bit/s]",
"Šířka pásma určuje maximální možnou přenosovou rychlost",
};
GtkWidget *build_net_unit5_exercise_page(void) {
return build_net_mcq_page(4, "netunit5", "net_ex5_title", "net_quiz5_head",
net5_qs, net5_hints,
(int)G_N_ELEMENTS(net5_qs));
}
const ChoiceQ net6_qs[] = {
{"Datový spoj slouží k:",
{"Jen měření amplitudy", "Výměně informací", "Jen FM modulaci",
"Jen tisku dokumentů"}, 4, 1},
{"Přenosová cesta je:",
{"Jen softwarová služba", "Fyzické médium přenosu",
"Jen CRC kód", "Jen peer‑to‑peer účet"}, 4, 1},
{"Mezi přenosová média patří:",
{"Jen parita", "Kabely, mikrovlny a družice", "Jen Baud",
"Jen start-bit"}, 4, 1},
{"Přenosový kanál je:",
{"Obousměrný vždy", "Jednosměrný souhrn prostředků pro spojení",
"Jen název serveru", "Jen typ QPSK"}, 4, 1},
{"Okruh vzniká:",
{"Z jednoho kanálu", "Ze dvou kanálů pro obousměrný přenos",
"Jen z parity", "Jen z Wi‑Fi hesla"}, 4, 1},
{"Trunking znamená:",
{"Odpojení všech kabelů", "Spojení více cest do jednoho okruhu",
"Jen asynchronní stop-bit", "Jen digitální 0 a 1"}, 4, 1},
{"Hlavní cíl trunkingu je:",
{"Snížit šířku pásma", "Zvýšit šířku pásma", "Zrušit kanály",
"Nahradit mainframe"}, 4, 1},
};
const char *net6_hints[] = {
"Datový spoj umožňuje výměnu informací mezi uzly",
"Fyzické médium: kabely, mikrovlny nebo družice",
"Fyzické médium: kabely, mikrovlny nebo družice",
"Kanál je jednosměrný souhrn prostředků pro spojení",
"Okruh tvoří dva kanály pro obousměrný přenos",
"Trunking spojuje více cest do jednoho okruhu",
"Trunking zvyšuje šířku pásma spojením cest",
};
GtkWidget *build_net_unit6_exercise_page(void) {
return build_net_mcq_page(5, "netunit6", "net_ex6_title", "net_quiz6_head",
net6_qs, net6_hints,
(int)G_N_ELEMENTS(net6_qs));
}
const ChoiceQ net7_qs[] = {
{"Multiplex znamená:",
{"Jen jeden uživatel na kanál",
"Rozdělení jednoho kanálu na více logických podkanálů",
"Jen CRC kontrolu", "Jen digitální 0 a 1"}, 4, 1},
{"FDM přiděluje každému kanálu:",
{"Časový slot", "Část frekvenčního pásma", "Jen start-bit",
"Jen mainframe"}, 4, 1},
{"TDM přiděluje každému kanálu:",
{"Část frekvenčního pásma", "Vyhrazený časový slot",
"Jen SaaS účet", "Jen paritu"}, 4, 1},
{"STDM:",
{"Garantuje vždy 100% dostupnost",
"Přiděluje kapacitu dle potřeby a negarantuje 100%",
"Je jen simplex", "Je jen trunking kabelů"}, 4, 1},
{"Simplex umožňuje přenos:",
{"Oběma směry současně", "Jen jedním směrem",
"Oběma směry, ale ne současně", "Jen přes CRC"}, 4, 1},
{"Half-duplex znamená:",
{"Jen jeden směr", "Oběma směry, ne současně",
"Oběma směry současně", "Jen FDM"}, 4, 1},
{"Full-duplex znamená:",
{"Jen jeden směr", "Oběma směry, ne současně",
"Oběma směry současně", "Jen STDM"}, 4, 2},
{"Agregace je:",
{"Sdílení kapacity kanálu více uživateli", "Jen fázová modulace",
"Jen dvoubodový spoj", "Jen stop-bit"}, 4, 0},
};
const char *net7_hints[] = {
"Multiplex dělí jeden kanál na více logických podkanálů",
"FDM: každému kanálu část frekvenčního pásma",
"TDM: každému kanálu vyhrazený časový slot",
"STDM přiděluje kapacitu dle potřeby, negarantuje 100 %",
"Simplex = jen jeden směr přenosu",
"Half-duplex = oběma směry, ale ne současně",
"Full-duplex = oběma směry současně",
"Agregace = sdílení kapacity kanálu více uživateli",
};
GtkWidget *build_net_unit7_exercise_page(void) {
return build_net_mcq_page(6, "netunit7", "net_ex7_title", "net_quiz7_head",
net7_qs, net7_hints,
(int)G_N_ELEMENTS(net7_qs));
}
const ChoiceQ net8_qs[] = {
{"Přepojování okruhů znamená:",
{"Pakety jdou vždy jinou cestou",
"Cesta se vytýčí předem a kapacita je garantována",
"Jen FDM multiplex", "Jen half-duplex"}, 4, 1},
{"Přepojování okruhů je vhodné pro:",
{"Jen náhodné datagramy bez cesty", "Přenos v reálném čase (jako telefon)",
"Jen CRC", "Jen peer‑to‑peer tisk"}, 4, 1},
{"Při přepojování paketů:",
{"Vždy existuje jedna pevná cesta",
"Každý paket může jít jinou cestou",
"Kapacita je vždy garantována", "Neexistují adresy"}, 4, 1},
{"Výhoda přepojování paketů je:",
{"Garantované pořadí vždy", "Reakce na zátěž a využití kapacity",
"Jen simplex", "Jen trunking"}, 4, 1},
{"Nevýhoda přepojování paketů je:",
{"Nereaguje na zátěž", "Negarantuje pořadí ani plynulost",
"Nelze použít adresy", "Vždy blokuje kanál jako telefon"}, 4, 1},
{"Pro video v reálném čase je přepojování paketů:",
{"Ideální vždy", "Spíše nevhodné kvůli plynulosti",
"Jediná možná metoda", "Stejné jako AM modulace"}, 4, 1},
{"Virtuální spoje:",
{"Nemají předem žádnou cestu",
"Mají cestu předem, prostředky jen při průchodu paketu",
"Jsou jen FDM", "Jsou jen parita"}, 4, 1},
{"Virtuální spoje slouží hlavně k:",
{"Zrušení paketů", "Zrychlení datagramů", "Jen simplexu",
"Jen analogovému signálu"}, 4, 1},
};
const char *net8_hints[] = {
"Cesta se vytýčí předem, kapacita je garantována",
"Cesta se vytýčí předem, kapacita je garantována",
"Data se dělí na pakety, každý může jít jinou cestou",
"Výhody: reakce na zátěž a lepší využití kapacity",
"Negarantuje pořadí ani plynulost – nevhodné pro živé video",
"Negarantuje pořadí ani plynulost – nevhodné pro živé video",
"Cesta je předem, prostředky se použijí jen při průchodu paketu",
"Virtuální spoje zrychlují přenos datagramů",
};
GtkWidget *build_net_unit8_exercise_page(void) {
return build_net_mcq_page(7, "netunit8", "net_ex8_title", "net_quiz8_head",
net8_qs, net8_hints,
(int)G_N_ELEMENTS(net8_qs));
}
const ChoiceQ net9_qs[] = {
{"Standardizace v sítích především:",
{"Zvyšuje nekompatibilitu", "Zajišťuje kompatibilitu mezi výrobci",
"Ruší protokoly", "Nahrazuje kabely"}, 4, 1},
{"Dekompozice znamená:",
{"Spojení všeho do jedné vrstvy",
"Rozklad složitého přenosu na vrstvy",
"Jen FDM", "Jen CRC"}, 4, 1},
{"Vrstvy komunikují:",
{"Se všemi vrstvami najednou", "Jen se sousedy přes rozhraní (SAP)",
"Jen přes satelit", "Jen bez protokolu"}, 4, 1},
{"Protokol je:",
{"Fyzický kabel", "Pravidla komunikace mezi stejnými vrstvami",
"Jen amplituda signálu", "Jen tiskový server"}, 4, 1},
{"Každá vrstva k datům typicky přidá:",
{"Jen stop-bit", "Hlavičku (header)", "Jen šířku pásma",
"Jen mainframe"}, 4, 1},
{"Jednotka linkové vrstvy se nazývá:",
{"Segment", "Paket", "Rámec", "Baud"}, 4, 2},
{"Jednotka síťové vrstvy se nazývá:",
{"Rámec", "Paket", "Segment", "Simplex"}, 4, 1},
{"Jednotka transportní vrstvy se nazývá:",
{"Rámec", "Paket", "Segment", "Trunk"}, 4, 2},
};
const char *net9_hints[] = {
"Standardizace zajišťuje kompatibilitu mezi výrobci",
"Dekompozice rozkládá přenos na jednotlivé vrstvy",
"Vrstvy komunikují jen se sousedy přes rozhraní SAP",
"Protokol = pravidla mezi stejnými vrstvami na různých uzlech",
"Každá vrstva přidává k datům hlavičku (header)",
"Rámec = linková, paket = síťová, segment = transportní",
"Rámec = linková, paket = síťová, segment = transportní",
"Rámec = linková, paket = síťová, segment = transportní",
};
GtkWidget *build_net_unit9_exercise_page(void) {
return build_net_mcq_page(8, "netunit9", "net_ex9_title", "net_quiz9_head",
net9_qs, net9_hints,
(int)G_N_ELEMENTS(net9_qs));
}
const ChoiceQ net10_qs[] = {
{"Model ISO/OSI má:",
{"4 vrstvy", "5 vrstev", "7 vrstev", "10 vrstev"}, 4, 2},
{"ISO/OSI je především:",
{"Jen typ kabelu", "Univerzální referenční model",
"Jen tiskový server", "Jen FDM"}, 4, 1},
{"Proč je ISO/OSI v praxi pomalejší?",
{"Nemá žádné vrstvy", "Každá vrstva řešila spolehlivost",
"Nepoužívá protokoly", "Nemá SAP"}, 4, 1},
{"TCP/IP v praxi:",
{"Prohrál proti ISO/OSI", "Zvítězil jako praktická architektura",
"Je jen analogový signál", "Je jen half-duplex"}, 4, 1},
{"TCP/IP vycházel z:",
{"Jen teoretických schémat bez praxe", "Skutečných potřeb sítí",
"Jen parity", "Jen trunkingu"}, 4, 1},
{"V TCP/IP spolehlivost řeší:",
{"Vždy jen fyzická vrstva", "Až vyšší vrstvy",
"Jen metalické kabely", "Jen mainframe"}, 4, 1},
};
const char *net10_hints[] = {
"ISO/OSI má 7 vrstev a je univerzální model",
"ISO/OSI má 7 vrstev a je univerzální model",
"V praxi je ISO/OSI pomalejší – spolehlivost řeší každá vrstva",
"TCP/IP zvítězil, protože vycházel ze skutečných potřeb",
"TCP/IP zvítězil, protože vycházel ze skutečných potřeb",
"V TCP/IP řeší spolehlivost až vyšší vrstvy",
};
GtkWidget *build_net_unit10_exercise_page(void) {
return build_net_mcq_page(9, "netunit10", "net_ex10_title", "net_quiz10_head",
net10_qs, net10_hints,
(int)G_N_ELEMENTS(net10_qs));
}
const ChoiceQ net11_qs[] = {
{"Fyzická vrstva se stará o:",
{"Přenos bitů", "Směrování paketů", "Navazování relací",
"Formátování ASCII"}, 4, 0},
{"MAC a LLC jsou podvrstvy:",
{"Síťové vrstvy", "Spojové (linkové) vrstvy", "Transportní vrstvy",
"Aplikační vrstvy"}, 4, 1},
{"Směrování paketů v sítích bez přímého spojení řeší:",
{"Fyzická vrstva", "Relační vrstva", "Síťová vrstva",
"Prezentační vrstva"}, 4, 2},
{"Transportní vrstva existuje:",
{"Jen v koncových uzlech", "I v routerech", "Jen ve switchech",
"Jen na hubu"}, 4, 0},
{"Relační vrstva především:",
{"Definuje napětí a kabely", "Navazuje, udržuje a ukončuje relace",
"Přidává MAC adresy", "Směruje pakety"}, 4, 1},
{"Komprese a šifrování patří do vrstvy:",
{"Fyzické", "Spojové", "Prezentační", "Síťové"}, 4, 2},
{"Aplikační vrstva poskytuje:",
{"CRC mezi sousedy", "Rozhraní pro programy (HTTP, FTP, e-mail…)",
"Jen duplex/simplex", "Jen směrování"}, 4, 1},
};
const char *net11_hints[] = {
"Fyzická vrstva přenáší bity a řeší médium",
"Spojová vrstva má podvrstvy MAC a LLC",
"Síťová vrstva směruje pakety i bez přímého spojení",
"Transportní vrstva je jen v koncových uzlech, ne v routerech",
"Relační vrstva řídí relace, dialog a synchronizaci",
"Prezentační vrstva formátuje data, komprimuje a šifruje",
"Aplikační vrstva je rozhraní pro programy a služby",
};
GtkWidget *build_net_unit11_exercise_page(void) {
return build_net_mcq_page(10, "netunit11", "net_ex11_title", "net_quiz11_head",
net11_qs, net11_hints,
(int)G_N_ELEMENTS(net11_qs));
}
const ChoiceQ net12_qs[] = {
{"Aplikační vrstva TCP/IP odpovídá v ISO/OSI:",
{"Jen aplikační vrstvě", "Aplikační + prezentační + relační",
"Jen fyzické vrstvě", "Linkové + síťové"}, 4, 1},
{"Vrstva síťového rozhraní TCP/IP odpovídá:",
{"Jen síťové ISO/OSI", "Linkové + fyzické ISO/OSI",
"Jen transportní ISO/OSI", "Jen aplikační ISO/OSI"}, 4, 1},
{"Model TCP/IP vznikl:",
{"Nejdřív model, pak protokoly", "Nejdřív protokoly, pak model",
"Současně s Token Ring", "Jen jako náhrada za ATM"}, 4, 1},
{"TCP je:",
{"Nespolehlivý a rychlý", "Spolehlivý a spojovaný",
"Jen směrovací protokol", "Jen fyzické kódování"}, 4, 1},
{"UDP je:",
{"Spolehlivý a spojovaný", "Nespolehlivý a rychlý",
"Jen e-mailový protokol", "Jen ARP"}, 4, 1},
{"HTTP, DNS a SMTP patří do vrstvy:",
{"Aplikační", "Transportní", "Síťové", "Síťového rozhraní"}, 4, 0},
{"IP, ICMP a OSPF patří do vrstvy:",
{"Aplikační", "Transportní", "Síťové (internetové)",
"Síťového rozhraní"}, 4, 2},
{"Ethernet a PPP patří do vrstvy:",
{"Aplikační", "Transportní", "Síťové", "Síťového rozhraní"}, 4, 3},
};
const char *net12_hints[] = {
"Aplikační TCP/IP = aplikační + prezentační + relační ISO/OSI",
"Síťové rozhraní TCP/IP = linková + fyzická ISO/OSI",
"U TCP/IP vznikly nejdřív protokoly, až pak model",
"TCP je spolehlivý a spojovaný",
"UDP je nespolehlivý a rychlý",
"HTTP, DNS a SMTP jsou aplikační protokoly",
"IP, ICMP a OSPF patří na síťovou (internetovou) vrstvu",
"Ethernet a PPP patří na vrstvu síťového rozhraní",
};
GtkWidget *build_net_unit12_exercise_page(void) {
return build_net_mcq_page(11, "netunit12", "net_ex12_title", "net_quiz12_head",
net12_qs, net12_hints,
(int)G_N_ELEMENTS(net12_qs));
}
const ChoiceQ net13_qs[] = {
{"Topologie sběrnice (bus) znamená, že:",
{"Každý uzel má vlastní centrální switch", "Médium sdílí všichni",
"Kabely tvoří jen zdvojený kruh", "Používá jen OSPF"}, 4, 1},
{"Nevýhoda sběrnice je hlavně:",
{"Že potřebuje hub u každého uzlu",
"Nízká bezpečnost a náchylnost na poruchu kabelu",
"Že nelze použít koaxiál", "Že zprávy neobíhají"}, 4, 1},
{"Topologie hvězda propojuje uzly přes:",
{"Jen jeden společný koaxiál bez centra",
"Centrální prvek (hub nebo switch)",
"Jen Token Ring", "Jen ATM"}, 4, 1},
{"Výhoda hvězdy je:",
{"Že přerušení jednoho kabelu k uzlu nevyřadí celou síť",
"Že všichni slyší vše", "Že nepotřebuje žádnou kabeláž",
"Že nemá aktivní prvky"}, 4, 0},
{"Hvězda typicky používá:",
{"Jen koaxiální kabel", "Kroucenou dvoulinku nebo optiku",
"Jen simplexní rádio", "Jen FDM"}, 4, 1},
{"V topologii kruh (ring):",
{"Zprávy obíhají, dokud nenajdou adresáta",
"Každý paket jde jen přes DNS",
"Médium sdílí hub bez kabelů",
"Neexistuje žádná kabeláž"}, 4, 0},
};
const char *net13_hints[] = {
"Sběrnice: médium sdílí všichni",
"Sběrnice: nízká bezpečnost a porucha kabelu vyřadí síť",
"Hvězda: uzly jdou přes hub nebo switch",
"Hvězda: porucha kabelu k uzlu nevyřadí celou síť",
"Hvězda používá kroucenou dvoulinku nebo optiku",
"V kruhu zprávy obíhají, dokud nenajdou adresáta",
};
GtkWidget *build_net_unit13_exercise_page(void) {
return build_net_mcq_page(12, "netunit13", "net_ex13_title", "net_quiz13_head",
net13_qs, net13_hints,
(int)G_N_ELEMENTS(net13_qs));
}
const ChoiceQ net14_qs[] = {
{"Princip optiky je:",
{"Převod el. impulsů na světlo a zpět fotodiodou",
"Jen směrování paketů OSPF", "Jen sdílená sběrnice",
"Jen UDP spojení"}, 4, 0},
{"Jedním vláknem je přenos:",
{"Vždy plně duplexní bez výjimky", "Jednosměrný (obousměrně dvě vlákna)",
"Jen poloviční kruh", "Jen Token Ring"}, 4, 1},
{"Výhoda optiky není:",
{"Imunita vůči el.mag. rušení", "Velký dosah a šířka pásma",
"Levná a snadná montáž konektorů", "Lepší ochrana proti odposlechu"}, 4, 2},
{"Mnohovidové vlákno (MM) má:",
{"Jádro 7–10 µm a vyžaduje laser", "Větší jádro 50/62,5 µm a více vidů",
"Jen koaxiální stínění", "Jen jednu MAC adresu"}, 4, 1},
{"Jednovidové vlákno (SM):",
{"Má větší jádro a LED zdroj", "Má malé jádro, jeden paprsek a laser",
"Nepřenáší světlo", "Funguje jen jako hub"}, 4, 1},
{"Levnější zdroje (LED) typicky patří k:",
{"Jednovidovým vláknům", "Mnohovidovým vláknům",
"Jen kruhové topologii", "Jen ATM"}, 4, 1},
};
const char *net14_hints[] = {
"Optika: el. impulsy → světlo (LED/laser) → fotodioda",
"Jedno vlákno = jednosměrný přenos; obousměrně dvě vlákna",
"Nevýhody: náročná montáž a cena prvků/konektorů",
"MM: jádro 50/62,5 µm a více vidů",
"SM: jádro 7–10 µm, jeden paprsek, laser",
"MM typicky používá levnější LED zdroje",
};
GtkWidget *build_net_unit14_exercise_page(void) {
return build_net_mcq_page(13, "netunit14", "net_ex14_title", "net_quiz14_head",
net14_qs, net14_hints,
(int)G_N_ELEMENTS(net14_qs));
}
const ChoiceQ net15_qs[] = {
{"Primární ochrana optického vlákna má průměr:",
{"900 µm", "250 µm", "50 µm", "7–10 µm"}, 4, 1},
{"Sekundární ochrana má průměr:",
{"250 µm", "900 µm", "62,5 µm", "1 km"}, 4, 1},
{"Těsná sekundární ochrana je vhodná hlavně:",
{"Pro svislé instalace", "Jen pro kruhovou topologii",
"Jen pro UDP", "Jen pro hub"}, 4, 0},
{"Volná sekundární ochrana je vhodná hlavně:",
{"Pro vodorovné instalace", "Jen pro ATM",
"Jen pro LED bez vlákna", "Jen pro sběrnici"}, 4, 0},
{"Montáž optiky vyžaduje:",
{"Jen nůžky na koaxiál", "Precizní lámání a svářečku vláken",
"Jen hub bez konektorů", "Jen Token Ring"}, 4, 1},
{"Při lámání se požaduje kolmost zhruba:",
{"Do 0,5°", "Do 45°", "Přesně 90° bez tolerance", "Bez významu"}, 4, 0},
};
const char *net15_hints[] = {
"Primární ochrana: 250 µm",
"Sekundární ochrana: 900 µm",
"Těsná sekundární ochrana: svislé instalace",
"Volná sekundární ochrana: vodorovné instalace",
"Montáž: lámačka a svářečka optických vláken",
"Lámání vyžaduje kolmost asi 0,5°",
};
GtkWidget *build_net_unit15_exercise_page(void) {
return build_net_mcq_page(14, "netunit15", "net_ex15_title", "net_quiz15_head",
net15_qs, net15_hints,
(int)G_N_ELEMENTS(net15_qs));
}
const ChoiceQ net16_qs[] = {
{"Kolize nastane, když:",
{"Na sdíleném médiu vysílá více uzlů najednou",
"Router vypne OSPF", "Vlákno má ochranu 250 µm",
"Použijeme jen TCP"}, 4, 0},
{"Metoda Aloha znamená především:",
{"Vysílej kdykoliv; bez potvrzení pošli znovu",
"Vždy rezervuj médium RTS/CTS",
"Nikdy nevysílej při tichu",
"Jen směrování RIP"}, 4, 0},
{"CSMA/CD se typicky pojí s:",
{"Wi-Fi", "Ethernetem", "Jen SMTP", "Jen ATM"}, 4, 1},
{"Při CSMA/CD uzel před vysíláním:",
{"Ignoruje médium", "Monitoruje nosnou (Carrier Sense)",
"Vždy čeká přesně 1 hodinu", "Použije jen laser"}, 4, 1},
{"Když CSMA/CD detekuje kolizi:",
{"Pokračuje vysíláním bez změny",
"Zastaví vysílání a zkusí to po náhodném čase",
"Přepne síť na sběrnici",
"Smaže IP adresu"}, 4, 1},
{"CSMA/CA na Wi-Fi předchází kolizím pomocí:",
{"RTS a CTS", "Jen CRC bez nosné", "Jen hubu", "Jen koaxiálu"}, 4, 0},
};
const char *net16_hints[] = {
"Kolize = více uzlů vysílá na sdíleném médiu najednou",
"Aloha: vysílej kdykoliv, při chybě znovu",
"CSMA/CD patří k Ethernetu",
"CSMA/CD nejdřív poslouchá nosnou (Carrier Sense)",
"Po kolizi CSMA/CD čeká náhodný čas a zkusí znovu",
"CSMA/CA rezervuje médium přes RTS/CTS",
};
GtkWidget *build_net_unit16_exercise_page(void) {
return build_net_mcq_page(15, "netunit16", "net_ex16_title", "net_quiz16_head",
net16_qs, net16_hints,
(int)G_N_ELEMENTS(net16_qs));
}
const ChoiceQ net17_qs[] = {
{"Repeater (opakovač) hlavně:",
{"Zesiluje signál a zvyšuje dosah", "Směruje IP pakety",
"Převádí mezi protokoly vyšších vrstev", "Rezervuje médium RTS/CTS"}, 4, 0},
{"Transceiver typicky:",
{"Převádí signál mezi různými médii", "Dělí síť jen podle DNS",
"Je vždy jen brána", "Pracuje jen s UDP"}, 4, 0},
{"Hub (rozbočovač) je:",
{"„Hloupý“ prvek – data z jednoho portu pošle všem ostatním",
"Směrovač na síťové vrstvě", "Jen laserový zdroj",
"Jen MAC filtr bez portů"}, 4, 0},
{"Bridge a switch pracují na vrstvě:",
{"Fyzické", "Linkové (rámce a MAC)", "Aplikační", "Jen transportní"}, 4, 1},
{"Switch mimo jiné:",
{"Dělí síť na kolizní domény", "Nikdy nepoužívá MAC adresy",
"Funguje jen jako hub bez portů", "Převádí jen ASCII"}, 4, 0},
{"Router pracuje s:",
{"Pakety a IP adresami a propojuje sítě", "Jen koaxiálem bez IP",
"Jen huby bez směrování", "Jen RTS/CTS"}, 4, 0},
{"Gateway (brána) především:",
{"Převádí mezi odlišnými architekturami/protokoly",
"Jen zesiluje bitový signál", "Jen tvoří kolize",
"Jen lámání vlákna"}, 4, 0},
};
const char *net17_hints[] = {
"Repeater zesiluje signál na fyzické vrstvě",
"Transceiver převádí mezi médii (např. metalika ↔ optika)",
"Hub rozešle přijatá data do všech ostatních portů",
"Bridge/switch = linková vrstva, rámce a MAC",
"Switch dělí síť na kolizní domény",
"Router = síťová vrstva, pakety a IP, propojuje sítě",
"Gateway převádí mezi odlišnými architekturami/protokoly",
};
GtkWidget *build_net_unit17_exercise_page(void) {
return build_net_mcq_page(16, "netunit17", "net_ex17_title", "net_quiz17_head",
net17_qs, net17_hints,
(int)G_N_ELEMENTS(net17_qs));
}
const ChoiceQ net18_qs[] = {
{"Switch se učí MAC adresy a ukládá je do:",
{"CAM tabulky", "Jen DNS cache", "Jen ARP bez portů", "Jen OSPF"}, 4, 0},
{"Díky CAM tabulce switch posílá rámce:",
{"Jen na konkrétní port", "Vždy na všechny porty jako hub",
"Jen na routery", "Jen přes laser"}, 4, 0},
{"Cut-through přepínání:",
{"Čte jen adresu příjemce a hned posílá",
"Vždy čeká na celé CRC", "Nikdy neposílá rámce",
"Pracuje jen s IP směrováním"}, 4, 0},
{"Nevýhoda cut-through je:",
{"Že posílá i chybné rámce", "Že je nejpomalejší",
"Že nemá MAC adresy", "Že vyžaduje gateway"}, 4, 0},
{"Store-and-forward:",
{"Přijme celý rámec, zkontroluje CRC a pak pošle",
"Čte jen první 2 byty", "Nikdy nekontroluje chyby",
"Funguje jen jako Aloha"}, 4, 0},
{"Fragment-free (modifikovaný cut-through) čte:",
{"Prvních 64 bytů (detekce kolizí)", "Jen poslední byte",
"Celý paket IP včetně směrování", "Jen SMTP hlavičku"}, 4, 0},
};
const char *net18_hints[] = {
"MAC adresy switch ukládá do CAM tabulky",
"Podle CAM tabulky posílá rámec jen na cílový port",
"Cut-through čte adresu příjemce a hned přeposílá",
"Cut-through je rychlý, ale propustí i chyby",
"Store-and-forward kontroluje celý rámec včetně CRC",
"Fragment-free čte prvních 64 bytů kvůli kolizím",
};
GtkWidget *build_net_unit18_exercise_page(void) {
return build_net_mcq_page(17, "netunit18", "net_ex18_title", "net_quiz18_head",
net18_qs, net18_hints,
(int)G_N_ELEMENTS(net18_qs));
}
const ChoiceQ net19_qs[] = {
{"Směrování probíhá na vrstvě:",
{"Fyzické", "Síťové (3. ISO/OSI)", "Jen aplikační", "Jen linkové"}, 4, 1},
{"Adaptivní (dynamické) algoritmy:",
{"Reagují na změny a vyměňují informace mezi směrovači",
"Nikdy nemění cesty", "Fungují jen na fyzické vrstvě",
"Nepoužívají metriku"}, 4, 0},
{"Neadaptivní (statické) směrování:",
{"Má cesty pevně nastavené správcem", "Samo opraví každý výpadek",
"Nepotřebuje směrovací tabulku", "Běží jen na Wi-Fi"}, 4, 0},
{"Centralizované směrování v praxi:",
{"Se skoro nepoužívá – výpadek centra shodí směrování",
"Je jediný standard internetu", "Neexistuje žádné centrum",
"Pracuje jen s MAC adresami"}, 4, 0},
{"Distribuované směrování znamená, že:",
{"Směrovače si vyměňují informace a každý má vlastní tabulku",
"Jedno centrum řídí všechny cesty", "Směrovač nezná žádné sousedy",
"Pakety jdou jen přes hub"}, 4, 0},
{"Metrika ve směrovací tabulce:",
{"Číselně hodnotí cestu – nižší je lepší",
"Je vždy jen MAC adresa", "Nemá vliv na výběr trasy",
"Nahrazuje next hop"}, 4, 0},
{"Distance Vector typicky:",
{"Posílá sousedům kopie tabulek a šíří informace krok za krokem",
"Počítá cesty jen v jednom centru", "Ignoruje přímé sousedy",
"Pracuje jen na aplikační vrstvě"}, 4, 0},
};
const char *net19_hints[] = {
"Směrování běží na síťové (3.) vrstvě ISO/OSI",
"Adaptivní algoritmy reagují na změny a sdílí stav sítě",
"Statické cesty nastaví správce a samy se nemění",
"Centralizované směrování padá s výpadkem centra",
"Distribuované: výměna informací a vlastní tabulky",
"Nižší metrika = lepší / rychlejší trasa",
"Distance Vector: výměna tabulek se sousedy (např. každých 30 s)",
};
GtkWidget *build_net_unit19_exercise_page(void) {
return build_net_mcq_page(18, "netunit19", "net_ex19_title", "net_quiz19_head",
net19_qs, net19_hints,
(int)G_N_ELEMENTS(net19_qs));
}
const ChoiceQ net20_qs[] = {
{"Směrovač (router) pracuje na vrstvě:",
{"Fyzické", "Síťové (3.)", "Jen aplikační", "Jen prezentační"}, 4, 1},
{"Router mimo jiné umožňuje:",
{"Segmentaci na podsítě a přístup na WAN", "Jen lámání optiky",
"Jen Aloha bez IP", "Jen cut-through bez MAC"}, 4, 0},
{"Firewall na routeru dokáže:",
{"Filtrovat pakety a řídit služby", "Jen zesílit bitový signál",
"Jen uložit CAM bez IP", "Jen nahradit fotodiodu"}, 4, 0},
{"Multiprotokolový router:",
{"Propojí sítě různých protokolů/standardů", "Umí jen jeden protokol",
"Nepracuje s IP adresou", "Nikdy nekonvertuje rámce"}, 4, 0},
{"Router rozděluje síť na:",
{"Broadcastové domény", "Jen fyzické kabely bez domén",
"Jen aplikační servery", "Jen Token Ring bez Ethernetu"}, 4, 0},
{"Brána (gateway) typicky:",
{"Připojuje LAN na odlišné prostředí (mainframe, GSM, WAN)",
"Pracuje jen jako hub", "Nikdy nemá software",
"Funguje jen na fyzické vrstvě"}, 4, 0},
{"Poznámka k pojmu brána:",
{"Někdy se jí myslí spíše router / LAN–WAN připojení",
"Vždy znamená jen fotodiodu", "Nikdy nesouvisí s internetem",
"Nahrazuje jen lámačku vláken"}, 4, 0},
};
const char *net20_hints[] = {
"Router pracuje na síťové (3.) vrstvě",
"Router segmentuje podsítě a zajišťuje WAN přístup",
"Firewall filtruje pakety a služby",
"Multiprotokolový router spojuje různé protokoly/standardy",
"Router dělí síť na broadcastové domény",
"Gateway připojuje LAN na odlišné prostředí",
"Pojem brána někdy označuje router nebo LAN–WAN připojení",
};
GtkWidget *build_net_unit20_exercise_page(void) {
return build_net_mcq_page(19, "netunit20", "net_ex20_title", "net_quiz20_head",
net20_qs, net20_hints,
(int)G_N_ELEMENTS(net20_qs));
}
const ChoiceQ net21_qs[] = {
{"Ethernetová adresa má:",
{"48 bitů (6 bytů) a je jedinečná", "Jen 16 bitů", "Jen 32 bitů IP",
"Jen 8 bitů SAP"}, 4, 0},
{"První 3 byty MAC adresy přiděluje:",
{"IEEE výrobci", "Jen uživatel v BIOS", "Jen DNS server",
"Jen Aloha"}, 4, 0},
{"Ethernet II v hlavičce používá:",
{"EtherType (např. IP = 0800h, hodnota > 1500)",
"Jen délku ≤ 1500 bez typu", "Jen FFFFh bez adres",
"Jen AAAAh bez MAC"}, 4, 0},
{"IEEE 802.3 místo EtherType má:",
{"Údaj o délce (≤ 1500) a uvnitř 802.2", "Jen cut-through",
"Jen 64 B MTU bez délky", "Jen laserovou hlavičku"}, 4, 0},
{"Raw 802.3 (Novell):",
{"Bez 802.2, jen IPX, začíná FFFFh", "Funguje jen s HTTP",
"Má vždy EtherType 0800h", "Nemá žádné adresy"}, 4, 0},
{"Maximální rámec Ethernet II je:",
{"1518 B (1500 + 18)", "64 B", "900 µm", "250 µm"}, 4, 0},
{"Minimální velikost rámce plyne z:",
{"Kolizního okénka (64 B)", "Jen z MTU routeru", "Jen z SNAP AAAAh",
"Jen z Token Ring"}, 4, 0},
};
const char *net21_hints[] = {
"MAC adresa Ethernetu má 48 bitů a je unikátní",
"IEEE přidělí výrobci první 3 byty adresy",
"Ethernet II: EtherType > 1500 (IP = 0800h)",
"IEEE 802.3: délka ≤ 1500 a rámec 802.2",
"Raw 802.3: Novell/IPX, začíná FFFFh",
"Max. Ethernet II = 1518 B",
"Min. rámec 64 B kvůli koliznímu okénku",
};
GtkWidget *build_net_unit21_exercise_page(void) {
return build_net_mcq_page(20, "netunit21", "net_ex21_title", "net_quiz21_head",
net21_qs, net21_hints,
(int)G_N_ELEMENTS(net21_qs));
}
const ChoiceQ net22_qs[] = {
{"IP protokol je:",
{"Nespojovaný a nespolehlivý přenos datagramů",
"Spolehlivý a spojovaný jako TCP", "Jen fyzické kódování",
"Jen EtherType bez IP"}, 4, 0},
{"Routing u IP znamená:",
{"Rozhodnutí o dalším směru datagramu", "Jen CRC na lince",
"Jen MAC učení ve switchi", "Jen lámání vlákna"}, 4, 0},
{"Forwarding u IP znamená:",
{"Vložení do linkového rámce a odeslání", "Jen výpočet metriky OSPF",
"Jen DNS překlad", "Jen Aloha"}, 4, 0},
{"HLEN (LENGTH) s hodnotou 5 znamená:",
{"Hlavičku dlouhou 20 B", "TTL 5", "PROTOCOL = 5", "MTU 5"}, 4, 0},
{"TTL v IP hlavičce:",
{"Počítá průchody směrovači a brání zacyklení",
"Udává EtherType", "Nahrazuje MAC adresu",
"Je vždy 1500"}, 4, 0},
{"Číslo protokolu 6 v IP hlavičce znamená:",
{"TCP", "UDP", "ICMP", "OSPF"}, 4, 0},
{"Číslo protokolu 17 znamená:",
{"UDP", "TCP", "IGMP", "ARP"}, 4, 0},
{"Ethernet MTU je typicky:",
{"1500 B", "64 kB", "576 B bez dat", "20 B hlavičky"}, 4, 0},
};
const char *net22_hints[] = {
"IP je nespojovaný a nespolehlivý",
"Routing = rozhodnutí o směru datagramu",
"Forwarding = vložení do rámce a odeslání",
"HLEN 5 = 5 × 4 B = 20 B hlavičky",
"TTL snižují směrovače proti zacyklení",
"PROTOCOL 6 = TCP",
"PROTOCOL 17 = UDP",
"Ethernet MTU = 1500 B",
};
GtkWidget *build_net_unit22_exercise_page(void) {
return build_net_mcq_page(21, "netunit22", "net_ex22_title", "net_quiz22_head",
net22_qs, net22_hints,
(int)G_N_ELEMENTS(net22_qs));
}
const ChoiceQ net23_qs[] = {
{"ICMP slouží především k:",
{"Zasílání informací o chybách a stavu přenosu",
"Jen směrování OSPF tabulek", "Jen lámání optiky",
"Jen EtherType 0800h"}, 4, 0},
{"ICMP paket se přenáší:",
{"Přímo v IP datagramu", "Jen jako Ethernet II bez IP",
"Jen v UDP bez IP", "Jen jako MAC bez datagramu"}, 4, 0},
{"Source Quench znamená:",
{"Varování před zahlcením – zpomal odesílání",
"TTL kleslo na 0", "Cíl je nedostupný", "Echo Reply"}, 4, 0},
{"Time Exceeded nastane, když:",
{"TTL v IP hlavičce klesne na 0", "Router nemá firewall",
"Použijeme jen SNAP", "MTU je 1500"}, 4, 0},
{"Echo Request / Reply využívá příkaz:",
{"ping", "lámačka", "cut-through", "hub"}, 4, 0},
{"Traceroute zjišťuje cestu tak, že:",
{"Postupně zvyšuje TTL a čeká na Time Exceeded",
"Posílá jen ARP bez IP", "Ignoruje směrovače",
"Používá jen CAM tabulku"}, 4, 0},
};
const char *net23_hints[] = {
"ICMP posílá informace o chybách a stavu přenosu",
"ICMP jede uvnitř IP datagramu",
"Source Quench = zpomal odesílání kvůli zahlcení",
"Time Exceeded = TTL kleslo na 0",
"Echo Request/Reply = ping",
"Traceroute zvyšuje TTL a čte Time Exceeded",
};
GtkWidget *build_net_unit23_exercise_page(void) {
return build_net_mcq_page(22, "netunit23", "net_ex23_title", "net_quiz23_head",
net23_qs, net23_hints,
(int)G_N_ELEMENTS(net23_qs));
}
const ChoiceQ net24_qs[] = {
{"ARP převádí:",
{"IP adresu na MAC adresu", "MAC adresu na IP adresu",
"TCP na UDP", "TTL na MTU"}, 4, 0},
{"RARP převádí:",
{"MAC adresu na IP adresu", "IP adresu na MAC adresu",
"EtherType na SAP", "OSPF na RIP"}, 4, 0},
{"Nejčastější způsob ARP je:",
{"Dotaz a odpověď v síti", "Jen ruční tabulka bez sítě",
"Jen cut-through", "Jen ICMP Echo"}, 4, 0},
{"ARP dotaz v Ethernetu používá:",
{"Broadcast", "Jen unicast bez broadcastu", "Jen laser",
"Jen Token Ring bez IP"}, 4, 0},
{"ARP odpověď typicky přichází jako:",
{"Unicast s MAC adresou uzlu", "Broadcast bez MAC",
"Jen Time Exceeded", "Jen Source Quench"}, 4, 0},
{"ARP cache slouží k tomu, aby:",
{"Se nemusely stále opakovat stejné dotazy",
"Se nahradil směrovač", "Se zrušila IP adresa",
"Se vypnul Ethernet"}, 4, 0},
};
const char *net24_hints[] = {
"ARP: IP → MAC",
"RARP: MAC → IP",
"Nejčastější je dynamický dotaz a odpověď",
"ARP dotaz jde broadcastem",
"ARP odpověď je unicast s MAC",
"ARP cache ukládá výsledky dočasně (arp -a)",
};
GtkWidget *build_net_unit24_exercise_page(void) {
return build_net_mcq_page(23, "netunit24", "net_ex24_title", "net_quiz24_head",
net24_qs, net24_hints,
(int)G_N_ELEMENTS(net24_qs));
}
const ChoiceQ net25_qs[] = {
{"TCP je:",
{"Spolehlivý a spojovaný", "Nespolehlivý a nespojovaný",
"Jen fyzická vrstva", "Jen ARP cache"}, 4, 0},
{"UDP je:",
{"Nespolehlivý a nespojovaný s malou režií",
"Spolehlivý se třícestným handshake", "Jen store-and-forward",
"Jen ICMP Time Exceeded"}, 4, 0},
{"Porty slouží k:",
{"Rozlišení aplikací na jednom uzlu", "Jen směrování IP",
"Jen MAC učení", "Jen lámání vlákna"}, 4, 0},
{"Navázání TCP spojení používá:",
{"Třícestné podání ruky (three-way handshake)",
"Jen broadcast ARP", "Jen Source Quench", "Jen cut-through"}, 4, 0},
{"Hlavička TCP má typicky:",
{"20 B (UDP 8 B)", "8 B (UDP 20 B)", "1500 B", "64 B min. rámec"}, 4, 0},
{"TCP není vhodný pro real-time média hlavně proto, že:",
{"Ztráta segmentu zastaví proud a čeká se na znovudoručení",
"Nemá žádné porty", "Nepodporuje unicast",
"Nemá hlavičku"}, 4, 0},
{"SCTP oproti TCP nabízí:",
{"Multihoming a multistreaming", "Jen Ethernet II",
"Jen RARP", "Jen hub flooding"}, 4, 0},
};
const char *net25_hints[] = {
"TCP = spolehlivý a spojovaný",
"UDP = nespolehlivý, nespojovaný, malá režie",
"Porty rozlišují aplikace na uzlu",
"TCP se navazuje three-way handshake",
"TCP hlavička 20 B, UDP 8 B",
"TCP čeká na znovudoručení – špatné pro real-time",
"SCTP: multihoming a multistreaming",
};
GtkWidget *build_net_unit25_exercise_page(void) {
return build_net_mcq_page(24, "netunit25", "net_ex25_title", "net_quiz25_head",
net25_qs, net25_hints,
(int)G_N_ELEMENTS(net25_qs));
}
const ChoiceQ net26_qs[] = {
{"Aplikační protokoly typicky posílají data přes:",
{"TCP nebo UDP", "Jen fyzickou vrstvu", "Jen ARP",
"Jen CAM tabulku"}, 4, 0},
{"Dva běžící procesy:",
{"Nesmí používat stejný port", "Musí sdílet jeden port",
"Nesmí mít žádný port", "Používají jen MAC"}, 4, 0},
{"Well-known porty mají rozsah:",
{"0–1023", "1024–49151", "49152–65535", "Jen 80–443"}, 4, 0},
{"Dynamické (privátní) porty jsou:",
{"49152–65535", "0–1023", "Jen 20–21", "Jen 3306"}, 4, 0},
{"Aplikační spojení určuje:",
{"Pětice (transport, IP1, port1, IP2, port2)",
"Jen MAC adresa", "Jen název souboru", "Jen VLAN ID"}, 4, 0},
{"HTTP a HTTPS používají porty:",
{"80 a 443", "22 a 23", "25 a 110", "53 a 67"}, 4, 0},
{"SSH a DNS mají porty:",
{"22 a 53", "80 a 443", "3389 a 5900", "20 a 21"}, 4, 0},
{"MySQL a RDP jsou typicky na portech:",
{"3306 a 3389", "80 a 443", "67 a 68", "161 a 162"}, 4, 0},
};
const char *net26_hints[] = {
"Aplikace posílají data přes TCP/UDP",
"Dva procesy nesmí sdílet stejný port",
"Well-known: 0–1023 (IANA)",
"Dynamické porty: 49152–65535",
"Spojení = pětice hodnot",
"HTTP 80, HTTPS 443",
"SSH 22, DNS 53",
"MySQL 3306, RDP 3389",
};
GtkWidget *build_net_unit26_exercise_page(void) {
return build_net_mcq_page(25, "netunit26", "net_ex26_title", "net_quiz26_head",
net26_qs, net26_hints,
(int)G_N_ELEMENTS(net26_qs));
}
const ChoiceQ net27_qs[] = {
{"Geostacionární družice létají asi:",
{"36 000 km nad Zemí", "16 km v troposféře", "50 km nad povrchem",
"Jen v nízké orbitě LEO"}, 4, 0},
{"Hlavní nevýhoda družicového spoje je:",
{"Velké zpoždění (~250–300 ms)", "Žádný broadcast",
"Jen kabelové médium", "Absence portů"}, 4, 0},
{"V síti VSAT komunikace probíhá:",
{"Jen mezi terminálem a hubem", "Přímo mezi dvěma terminály",
"Jen přes ARP", "Jen přes WEP"}, 4, 0},
{"Mikrovlnný spoj typicky vyžaduje:",
{"Přímou viditelnost (dosah ~50 km)", "Jen metalický kabel",
"Jen port 80", "Jen WEP klíč"}, 4, 0},
{"V infrastruktuře Wi-Fi stanice (STA):",
{"Komunikují přes AP, ne přímo mezi sebou",
"Vždy jen ad-hoc bez AP", "Nepoužívají ESSID",
"Běží jen na 36 000 km"}, 4, 0},
{"802.11ax (Wi-Fi 6) přináší zejména:",
{"OFDMA a vysokou kapacitu", "Jen WEP", "Jen C-band 4/6 GHz",
"Jen troposférický odraz"}, 4, 0},
{"WEP je dnes:",
{"Prolomený a nevhodný", "Nejbezpečnější volba",
"Totéž co WPA3-SAE", "Povinný od roku 2006"}, 4, 0},
{"Doporučené zabezpečení Wi-Fi je:",
{"WPA2/WPA3 s AES (ne WEP)", "Jen Open system WEP",
"Jen Shared key WEP", "Bez hesla vždy"}, 4, 0},
};
const char *net27_hints[] = {
"Geostacionární družice ~36 000 km",
"Družice: zpoždění stovky ms",
"VSAT: jen terminál ↔ hub",
"Mikrovlny: přímá viditelnost ~50 km",
"STA komunikují přes AP",
"Wi-Fi 6 (ax): OFDMA",
"WEP prolomen – nepoužívat",
"Používej WPA2/WPA3 + AES",
};
GtkWidget *build_net_unit27_exercise_page(void) {
return build_net_mcq_page(26, "netunit27", "net_ex27_title", "net_quiz27_head",
net27_qs, net27_hints,
(int)G_N_ELEMENTS(net27_qs));
}