3651 lines
135 KiB
C
3651 lines
135 KiB
C
#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–25 = source topics (Základní pojmy … TCP/UDP). */
|
||
{ .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" },
|
||
};
|
||
|
||
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"
|
||
};
|
||
|
||
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);
|
||
}
|
||
|
||
/* 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));
|
||
}
|
||
|