Лабораторная работа. Исследуем сокеты. Часть 3 (окончание)::Журнал СА 06.2016
www.samag.ru
     
Поиск   
              
 www.samag.ru    Web  0 товаров , сумма 0 руб.
E-mail
Пароль  
 Запомнить меня
Регистрация | Забыли пароль?
Журнал "Системный администратор"
Журнал «БИТ»
Подписка
Архив номеров
Где купить
Наука и технологии
Авторам
Рекламодателям
Контакты
   

  Опросы
  Статьи

Событие  

В банке рассола ждет сисадмина с полей фрактал-кукумбер

Читайте впечатления о слете ДСА 2024, рассказанные волонтером и участником слета

 Читать далее...

Организация бесперебойной работы  

Бесперебойная работа ИТ-инфраструктуры в режиме 24/7 Как обеспечить ее в нынешних условиях?

Год назад ИТ-компания «Крок» провела исследование «Ключевые тренды сервисного рынка 2023». Результаты

 Читать далее...

Книжная полка  

Читайте и познавайте мир технологий!

Издательство «БХВ» продолжает радовать выпуском интересных и полезных, к тому же прекрасно

 Читать далее...

СУБД PostgreSQL  

СУБД Postgres Pro

Сертификация по новым требованиям ФСТЭК и роль администратора без доступа к данным

 Читать далее...

Критическая инфраструктура  

КИИ для оператора связи. Готовы ли компании к повышению уровня кибербезопасности?

Похоже, что провайдеры и операторы связи начали забывать о требованиях законодательства

 Читать далее...

Архитектура ПО  

Архитектурные метрики. Качество архитектуры и способность системы к эволюционированию

Обычно соответствие программного продукта требованиям мы проверяем через скоуп вполне себе понятных

 Читать далее...

Как хорошо вы это знаете  

Что вам известно о разработках компании ARinteg?

Компания ARinteg (ООО «АРинтег») – системный интегратор на российском рынке ИБ –

 Читать далее...

Графические редакторы  

Рисование абстрактных гор в стиле Paper Cut

Векторный графический редактор Inkscape – яркий представитель той прослойки open source, с

 Читать далее...

День сисадмина  

Учите матчасть! Или как стать системным администратором

Лето – время не только отпусков, но и хорошая возможность определиться с профессией

 Читать далее...

День сисадмина  

Живой айтишник – это всегда движение. Остановка смерти подобна

Наши авторы рассказывают о своем опыте и дают советы начинающим системным администраторам.

 Читать далее...

Виртуализация  

Рынок решений для виртуализации

По данным «Обзора российского рынка инфраструктурного ПО и перспектив его развития», сделанного

 Читать далее...

Книжная полка  

Как стать креативным и востребованным

Издательский дом «Питер» предлагает новинки компьютерной литературы, а также книги по бизнесу

 Читать далее...

Книжная полка  

От создания сайтов до разработки и реализации API

В издательстве «БХВ» недавно вышли книги, которые будут интересны системным администраторам, создателям

 Читать далее...

Разбор полетов  

Ошибок опыт трудный

Как часто мы легко повторяем, что не надо бояться совершать ошибки, мол,

 Читать далее...

1001 и 1 книга  
19.03.2018г.
Просмотров: 6188
Комментарии: 0
Машинное обучение с использованием библиотеки Н2О

 Читать далее...

12.03.2018г.
Просмотров: 6898
Комментарии: 0
Особенности киберпреступлений в России: инструменты нападения и защита информации

 Читать далее...

12.03.2018г.
Просмотров: 4181
Комментарии: 0
Глубокое обучение с точки зрения практика

 Читать далее...

12.03.2018г.
Просмотров: 2986
Комментарии: 0
Изучаем pandas

 Читать далее...

12.03.2018г.
Просмотров: 3791
Комментарии: 0
Программирование на языке Rust (Цветное издание)

 Читать далее...

19.12.2017г.
Просмотров: 3802
Комментарии: 0
Глубокое обучение

 Читать далее...

19.12.2017г.
Просмотров: 6296
Комментарии: 0
Анализ социальных медиа на Python

 Читать далее...

19.12.2017г.
Просмотров: 3150
Комментарии: 0
Основы блокчейна

 Читать далее...

19.12.2017г.
Просмотров: 3445
Комментарии: 0
Java 9. Полный обзор нововведений

 Читать далее...

16.02.2017г.
Просмотров: 7261
Комментарии: 0
Опоздавших не бывает, или книга о стеке

 Читать далее...

17.05.2016г.
Просмотров: 10627
Комментарии: 0
Теория вычислений для программистов

 Читать далее...

30.03.2015г.
Просмотров: 12348
Комментарии: 0
От математики к обобщенному программированию

 Читать далее...

18.02.2014г.
Просмотров: 13979
Комментарии: 0
Рецензия на книгу «Читаем Тьюринга»

 Читать далее...

13.02.2014г.
Просмотров: 9109
Комментарии: 0
Читайте, размышляйте, действуйте

 Читать далее...

12.02.2014г.
Просмотров: 7063
Комментарии: 0
Рисуем наши мысли

 Читать далее...

10.02.2014г.
Просмотров: 5373
Комментарии: 3
Страна в цифрах

 Читать далее...

18.12.2013г.
Просмотров: 4603
Комментарии: 0
Большие данные меняют нашу жизнь

 Читать далее...

18.12.2013г.
Просмотров: 3412
Комментарии: 0
Компьютерные технологии – корень зла для точки роста

 Читать далее...

04.12.2013г.
Просмотров: 3142
Комментарии: 0
Паутина в облаках

 Читать далее...

03.12.2013г.
Просмотров: 3388
Комментарии: 0
Рецензия на книгу «MongoDB в действии»

 Читать далее...

02.12.2013г.
Просмотров: 3010
Комментарии: 0
Не думай о минутах свысока

 Читать далее...

Друзья сайта  

 Лабораторная работа. Исследуем сокеты. Часть 3 (окончание)

Архив номеров / 2016 / Выпуск №6 (163) / Лабораторная работа. Исследуем сокеты. Часть 3 (окончание)

Рубрика: Карьера/Образование /  Лабораторная работа

Без фото ВЛАДИМИР ЗАКЛЯКОВ, советник налоговой службы 2-го ранга

Лабораторная работа
Исследуем сокеты. Часть 3 (окончание)

В предыдущих номерах [1, 2] был описан инструментарий для проведения исследований. В данной части предлагается самостоятельно выполнить ряд практических заданий

Начнём эксперименты

Теперь, когда вам известны цели работы, схема исследований, устройство и подготовка лабораторного стенда (см. [1, 2]), в данной завершающей части вам предстоит почувствовать себя исследователем и выполнить несколько несложных практических заданий самостоятельно, после чего вы сможете оценить полученные результаты и связать свои теоретические знания с практикой.

Возможно, не лишним будет программа TCP-сервер на языке Си, поэтому приводим её ниже.

tcp_server1.с – простой TCP-сервер, обрабатывающий одновременно одно соединение

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <stdio.h>

#include <stdlib.h>

#include <netdb.h>

#include <string.h>

// номер порта для приёма входящих соединений сервером

#define PORTNUM 1234

int main(void)

{

int listen_s, connected_s, nbytes;

struct sockaddr_in serv_addr, clnt_addr;

char buf[256]; // буфер для приёма сообщения

unsigned long addr;

if ( (listen_s=socket(PF_INET, SOCK_STREAM, 0) ) == -1 )

{

perror("Ошибка вызова socket()");

exit(1);

}

/* Заполняем, предварительно обнулив, структуру serv_addr

для описания «своего» конца коммуникационного канала:

указываем семейство адресов AF_INET (то есть IP-адреса);

входящий адрес сокета INADDR_ANY (0.0.0.0) означает

принимать соединения на всех имеющихся у хоста адресах. */

bzero(&serv_addr, sizeof(serv_addr));

serv_addr.sin_family=AF_INET;

serv_addr.sin_addr.s_addr=INADDR_ANY;

serv_addr.sin_port=htons((u_short)PORTNUM);

/* Связываем сокет listen_s с адресом и портом,

содержащимися в serv_addr, определяя локальную часть

коммуникационного канала. */

if ( bind(listen_s, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1 )

{

perror("Ошибка вызова bind()");

exit(2);

}

/* Переводим сокет в режим ожидания соединений – фактически

в модуль TCP передаётся вызов PASSIVE_OPEN. Второй параметр

задаёт максимальный размер, до которого может расти очередь

ожидающих соединений у listen_s. */

if ( listen(listen_s,10)==-1 )

{

perror("Ошибка вызова listen()");

exit(3);

}

printf("Сервер готов принимать соединения\n");

/* Обнуляем структуру clnt_addr, в которую будут записаны

адрес и порт подсоединившегося клиента. */

int addrlen;

bzero(&clnt_addr, sizeof(clnt_addr));

addrlen=sizeof(clnt_addr);

/* Принимаем запрос. Возврат из функции accept()

производится только после поступления запроса

и установления соединения с клиентом. При этом на базе

старого сокета listen_s создаётся новый сокет connected_s,

у которого определены уже обе части соединения – локальная

и удалённая. Таким образом, сокет connected_s уже может

использоваться для передачи данных. Адрес и порт

подсоединившегося клиента возвращаются в структуре

clnt_addr. */

if ( (connected_s=accept(listen_s, (struct sockaddr *)&clnt_addr, &addrlen) ) == -1 )

{

perror("Ошибка вызова accept()");

exit(4);

}

printf("Соединение от %s\n", inet_ntoa(clnt_addr.sin_addr));

 

nbytes=recv(connected_s, buf, sizeof(buf)-1, 0);

if (nbytes>0)

{

buf[nbytes]='\0';

printf("Получено сообщение: %s\n", buf);

}

printf("Завершаем работу, закрываем сокет.\n");

close(connected_s);

close(listen_s);

exit(0);

}

Самостоятельная доработка программ

Программа, реализующая серверную часть TCP-сокета, способна принимать лишь одно входное соединение одновременно. На практике же практикуются множественные клиентские подключения одновременно. Такую возможность можно добавить за счёт использования функции fork(). Она создаёт дубликат процесса, возвращая в родительский процесс идентификатор порождённого дочернего процесса, а в дочерний – ноль. Это позволит одновременно делать две вещи: работать с установленным соединением через сокет connected_s, а дубликату процесса продолжать принимать новые соединения через старый сокет listen_s.

Также программа принимает лишь одно сообщение от клиента и завершает работу. На практике можно реализовать приём нескольких сообщений циклом.

На сервере или на клиенте может иметься возможность автоответа, то есть автоматическое отправление противоположной стороне сообщения в ответ на приём какого-то ключевого слова или команды.

Задания для пошагового выполнения

Шаг 1. Войдите в систему.

Шаг 2. Запустите три терминальных окна: для клиента, для сервера и для исследования.

Шаг 3. Запустите прослушивать сокет на порту 1234 протокола TCP на серверной стороне:

$ nc -l 1234

Шаг 4. В окне для исследования просмотрите занятость портов для протокола TCP:

$ netstat -t -a -n

...

tcp 0 0 0.0.0.0:1234 0.0.0.0:* LISTEN

...

$ ss -t -a -n

...

LISTEN 0 1 *:1234 *:*

...

Найдите в выводе строку, отвечающую за ваш прослушивающий сокет.

Шаг 5. Запустите последовательно команды

$ lsof

$ lsof -i

$ lsof -i TCP -n -P

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

nc 2691 user 3u IPv4 20425 0t0 TCP *:1234 (LISTEN)

Сравните вывод и найдите PID процесса, ожидающего подключения на порту 1234 протокола TCP.

Шаг 6. Запустите команду:

$ ps aux

Найдите среди списка всех процессов тот, что отвечает за работу серверного сокета.

Шаг 7. Запустите сниффер.

$ su -

(введите пароль для повышения своих прав, выход из этого режима – exit)

# tcpdump -i lo -n

Он начнёт перехватывать данные на интерфейсе lo.

Шаг 8. Перейдите в окно клиента и подключитесь к серверу:

$ nc 127.0.0.1 1234

Обратите внимание на то, что после подключения в окне диагностики сниффер покажет информацию о прохождении нескольких пакетов.

09:51:01.490961 IP 127.0.0.1.54908 > 127.0.0.1.search-agent: Flags [S], seq 1468622890, win 65495, options [mss 65495,sackOK,TS val 1444852 ecr 0,nop,wscale 7], length 0

09:51:01.490982 IP 127.0.0.1.search-agent > 127.0.0.1.54908: Flags [S.], seq 2911204310, ack 1468622891, win 65483, options [mss 65495,sackOK,TS val 1444852 ecr 1444852,nop,wscale 7], length 0

09:51:01.490994 IP 127.0.0.1.54908 > 127.0.0.1.search-agent: Flags [.], ack 1, win 512, options [nop,nop,TS val 1444852 ecr 1444852], length 0

Это клиент и сервер установили соединение.

Шаг 9. Наберите на стороне клиента «Привет сервер! Hello server!» и отправьте его на сервер нажатием <Enter>. Сниффер покажет перехват ещё одного пакета. В окне сервера появится отправленное сообщение.

09:53:24.397337 IP 127.0.0.1.54908 > 127.0.0.1.search-agent: Flags [P.], seq 1:42, ack 1, win 512, options [nop,nop,TS val 1587758 ecr 1444852], length 41

09:53:24.397564 IP 127.0.0.1.search-agent > 127.0.0.1.54908: Flags [.], ack 42, win 512, options [nop,nop,TS val 1587758 ecr 1587758], length 0

Шаг 10. Выполните такую же операцию на стороне сервера, отправив клиенту сообщение «Привет клиент! Hello client!».

Клиент получит сообщение, а сниффер зафиксирует факт передачи данных.

09:54:37.185271 IP 127.0.0.1.search-agent > 127.0.0.1.54908: Flags [P.], seq 1:42, ack 42, win 512, options [nop,nop,TS val 1660546 ecr 1587758], length 41

09:54:37.185317 IP 127.0.0.1.54908 > 127.0.0.1.search-agent: Flags [.], ack 42, win 512, options [nop,nop,TS val 1660546 ecr 1660546], length 0

Шаг 11. Прервите работу сниффера нажатием <CTRL> + <C>. Что означает «127.0.0.1.search-agent»?

Внимательно просмотрите файл /etc/services (например используя cat и фильтр grep 1234) и вспомните, что у tcpdump есть также ключ -nn, используйте его в следующий раз.

Шаг 12. Ответьте на вопросы: сколько пакетов было передано в результате информационного обмена клиента с сервером? Сколько пакетов было от клиента к серверу? Сколько пакетов было в обратном направлении? Какого размера (параметр length) были пакеты? Это размер с заголовками канального/сетевого уровня или нет?

Шаг 13. В окне для диагностики выполните запуск команд:

$ lsof -i TCP -n -P

$ lsof -i TCP -n -P | grep 1234

$ ss -t -a -n

$ ss -t -a -n | grep 1234

$ netstat -t -a -n

$ netstat -t -a -n | grep 1234

Оцените, что изменилось по сравнению c выводом при выполнении команд из шагов 4 и 5.

Поскольку вы видите статистику одновременно и для клиента и для сервера, то вы будете видеть сокет клиента в режиме установленного соединения (ESTABLISHED), сокет сервера в режиме установленного соединения (ESTABLISHED), а также сокет сервера в режиме прослушивания (LISTEN), поскольку команда nc может принять ещё одно соединение.

Шаг 14. Если у серверной части nc имеется слушающий сокет, то сможет ли к нему подключиться ещё один nc-клиент и передать сообщение? Запустите ещё одно окно терминала ивыполните команду по запуску второго клиента:

$ nc 127.0.0.1 1234

Отправьте с обоих клиентов и с сервера сообщения и проследите, кто их получит.

Может создаться впечатление, что соединение у второго клиента есть, но данные не передаются.

Посмотрите список открытых файлов и сравните его с п.13:

$ lsof -i TCP -n -P | grep 1234

Что поменялось? Обратите внимание на номера процессов (вторая колонка – PID) в выводе.

Ответьте, является ли соединение второго клиента полноценно установленным?

Шаг 15. Прервите выполнение серверов и клиентов, нажимая <CTRL> + <C>.

Шаг 16. Запустите сниффер и сервер повторно, но с другими ключами:

# tcpdump -i lo -n -nn -X -s 200

$ nc -l 1234 -v

Шаг 17. Подключитесь клиентом. Повторите посылку сообщений «Привет сервер! Hello server!» и «Привет клиент! Hello client!». Видите ли вы среди перехваченных данных ваше сообщение? Видите ли вы байты, отвечающие за кириллицу?

10:33:08.363361 IP 127.0.0.1.54920 > 127.0.0.1.1234: Flags [P.], seq 1:42, ack 1, win 512, options [nop,nop,TS val 3971724 ecr 3949456], length 41

0x0000: 4500 005d a1ad 4000 4006 9aeb 7f00 0001 E..]..@.@.......

0x0010: 7f00 0001 d688 04d2 1b2f e225 7605 3290 ........./.%v.2.

0x0020: 8018 0200 fe51 0000 0101 080a 003c 9a8c .....Q.......<..

0x0030: 003c 4390 d09f d180 d0b8 d0b2 d0b5 d182 .<C.............

0x0040: 20d1 81d0 b5d1 80d0 b2d0 b5d1 8021 2048 .............!.H

0x0050: 656c 6c6f 2073 6572 7665 7221 0a ello.server!.

Шаг 18. Оставьте сниффер включённым. Прервите выполнение клиента и сервера. Запустите сервер повторно. Запустите браузер Firefox.

Возможно, вы увидите с помощью сниффера, что браузер уже во время своего запуска сгенерировал достаточно трафика. Сервер будет в это время «молчать», ожидая входящие соединения.

Шаг 19. Обратитесь к серверу через браузер Firefox, введя в адресной строке http://127.0.0.1:1234.

После сообщения от nc о подключении (в старых версиях nc может не показываться):

Connection from 127.0.0.1 port 1234 [tcp/search-agent] accepted

вы увидите HTTP-запрос браузера:

GET / HTTP/1.1

Host: 127.0.0.1:1234

User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Connection: keep-alive

Далее браузер, думая, что подключился к полноценному веб-серверу, будет ожидать ответ.

Вероятнее всего, он захочет получить в ответ что-то вида Content-Type: text/html и два символа перевода строки – типичный HTTP-заголовок ответа сервера, а затем и запрошенный корневой файл с сервера – «/».

Вы можете игнорировать эти правила обмена (рекомендуемые RFC 2616 и др.), ввести любой текст и закрыть соединение на стороне сервера нажатием <CTRL> + <С>.

После этого браузер отобразит полученный от сервера текст.

Шаг 20. Запустите сервер заново и обратитесь к нему с помощью консольного браузера lynx.

$ lynx 127.0.0.1:1234

Обратите внимание, что запрос, передаваемый серверу, несколько отличается.

GET / HTTP/1.0

Host: 127.0.0.1:1234

Accept: text/html, text/plain, text/css, text/sgml, */*;q=0.01

Accept-Encoding: gzip, bzip2

Accept-Language: en

User-Agent: Lynx/2.8.6rel.5 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/1.0.0-fips

Шаг 21. Используйте для обращения wget:

$ wget 127.0.0.1:1234

На сервер придёт, отобразившись в окне со сниффером, следующий запрос:

GET / HTTP/1.0

User-Agent: Wget/1.12 (linux-gnu)

Accept: */*

Host: 127.0.0.1:1234

Connection: Keep-Alive

Шаг 22. Завершите выполнение сервера nc.

Шаг 23. Обратитесь с помощью браузеров Firefox, lynx и программы wget на локальный веб-сервер на 80-м порту и IP – 127.0.0.1.

Изучите информационный обмен клиентов с сервером в окне со сниффером для всех трёх случаев.

Если надумаете обратиться к какому-либо серверу в локальной сети или в интернете, то обратите внимание, что сниффер у вас запущен на интерфейсе lo, а обращение в сеть идёт через eth0 (или иной).

Шаг 24. Смоделируйте с помощью утилит nc и telnet работу браузера, для этого обратитесь к серверу с HTTP GET-запросом, передав ему строку GET / или GET / HTTP/1.0. В ответ вы получите тестовую страницу. Сниффер покажет прошедшие через интерфейс данные:

$ telnet 127.0.0.1 80

Connected to 127.0.0.1.

Escape character is '^]'.

GET /

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<head>

...

</html>

Connection closed by foreign host.

$ nc 127.0.0.1 80

GET /

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

...

Шаг 25. Запустите nc как сервер для прослушивания порта 1234 протокола TCP:

$ nc 1234 -l

Шаг 26. Скомпилируйте программу tcp_client1.c (см. [1, 2]):

$ gcc tcp_client1.c -o tcp_client1

Шаг 27. Запустите клиент протокола TCP:

$ ./tcp_client1

Дошли ли данные от программы клиента до сервера? Увидели ли вы их с помощью сниффера?

Почему сервер закончил прослушивать соединение?

Шаг 28. Запустите сниффер tshark и повторите шаги 25 и 27.

# tshark -i lo -n -x

Удалось ли вам увидеть переданное сообщение среди информации, перехваченной сниффером?

0.001907785 127.0.0.1 -> 127.0.0.1 TCP 87 54953 > 1234 [PSH, ACK] Seq=1 Ack=1 Win=65536 Len=21 TSval=6717342 TSecr=6717340

0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 ..............E.

0010 00 49 fe 1e 40 00 40 06 3e 8e 7f 00 00 01 7f 00 .I..@.@.>.......

0020 00 01 d6 a9 04 d2 b7 af 81 81 35 b3 5e 85 80 18 ..........5.^...

0030 02 00 fe 3d 00 00 01 01 08 0a 00 66 7f 9e 00 66 ...=.......f...f

0040 7f 9c d0 9f d1 80 d0 b8 d0 b2 d0 b5 d1 82 21 20 ..............!

0050 48 65 6c 6c 6f 21 0a Hello!.

Шаг 29. Повторите действия шага 28, добавив в строке запуска tshark ключ -V.

Насколько больше полезной информации выдал сниффер?

Шаг 30. Скомпилируйте TCP-сервер:

$ gcc tcp_server1.c -o tcp_server1

Шаг 31. Запустите TCP-сервер, подключитесь к нему с помощью nc и пошлите сообщение «Привет!».

$./tcp_server1

$ nc 127.0.0.1 1234

Привет

Сервер готов принимать соединения.

Соединение от 127.0.0.1

Получено сообщение: Привет

Завершаем работу, закрываем сокет.

Шаг 32. Проверьте работу TCP-клиента и TCP-сервера вместе.

Шаг 33. Повторите Шаг 32 с минимальной задержкой.

Если между шагами 32 и 33 прошло менее минуты, то не получили ли вы при попытке запуска сервера сообщение об ошибке?

Ошибка вызова bind(): Address already in use

Если да, то попытайтесь устранить ошибку, воспользовавшись советом ниже по устранению этой проблемы.

Замечание. Можно заметить, что довольно часто при повторном запуске программы, использующей TCP-серверные сокеты, выдаётся сообщение вида «Ошибка вызова bind(): Address already in use». Однако через какое-то время та же самая программа запускается и работает без этого сообщения.

Подробно эта ситуация описана в [3]. Коротко: ситуация происходит потому, что сокеты, установившие соединение, всё ещё «висят» в ядре ОС, и оно «держит» порт занятым. Решение либо подождать (минуту или около того), пока ядро не освободит порт, либо, что более правильно, добавить в программу вызов функции setsockopt(), что позволит повторно использовать уже свободный порт без ожиданий. Для программы tcp_server1.с строки, избавляющие пользователя от указанной ошибки и ожидания, будут выглядеть следующим образом:

// избавляемся от ошибки bind(): Address already in use

int opt = 1;

if (setsockopt(listen_s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) == -1)

{

perror("Ошибка вызова setsockopt()");

exit(5);

}

Добавьте вышеприведённый код в файл tcp_server1.c после вызова функции socket() перед вызовом функции bind().

Шаг 34. Перезапустите сниффер с параметрами:

# tshark -i lo -n -x

Создайте UDP, слушающий сокет, на порту 1234:

$ nc -l 1234 -u

Шаг 35. Исследуйте серверный сокет командами lsof, netstat и ss, повторив шаги 4, 5, 6. Запомните вывод команды lsof -i -n -P.

Шаг 36. Поключитесь с помощью nc как клиент к UDP-серверу:

$ nc 127.0.0.1 1234 -u

Показал ли сниффер какой-то трафик во время запуска клиента, как это было при установлении TCP-соединения?

Шаг 37. Исследуйте открытые сокеты системы командами lsof, netstat и ss, повторив шаги 4, 5, 6. Как изменился после подключения вывод команды lsof -i -n -P? Видите ли разницу по сравнению с использованием TCP-сокетов?

Шаг 38а. Пошлите сообщения от клиента серверу и обратно. Проанализируйте трафик, перехваченный сниффером. Как изменился вывод команды lsof -i -n -P?

Шаг 38б. Пошлите сообщения от сервера клиенту и обратно. Проанализируйте трафик, перехваченный сниффером. Как изменился вывод команды lsof -i -n -P?

Шаг 38в. В чём разница при выполнении между ветками 34-35-36-37-38а и 34-35-36-37-38б?

Как изменился после подключения вывод команды lsof -i -n -P?

Шаг 39. Завершите клиентский nc нажатием <CTRL> + <C>.

Шаг 40. Запустите клиента повторно и отправьте сообщение серверу:

$ nc 127.0.0.1 1234 -u

Получил ли сервер сообщение? Был ли сетевой трафик (что зафиксировал сниффер)?

Не выдал ли клиент похожую ошибку?

nc: Write error: Connection refused

Почему так произошло?

Шаг 41. Проанализируйте ситуацию, возникшую на шаге 40, с помощью lsof, netstat и ss, повторив шаги 4, 5, 6.

Возможно ли из вывода этих программ понять, почему нет обмена трафиком между клиентским и серверным приложениями?

Как решить проблему, чтобы была связь между сервером и клиентом?

Шаг 42. Скомпилируйте UDP-клиент (см. [1, 2]):

$ gcc udp_client1.c -o udp_client1

Шаг 43. Проверьте работу клиента с помощью сервера на nc. Для этого заново запустите UDP-сервер:

$ nc -l 1234 -u

а после этого запустите UDP-клиент.

$ ./udp_client1

Была ли осуществлена передача данных клиентом? Увидел ли передачу данных сниффер? Получил и отобразил ли полученные данные сервер?

Шаг 44. Обратите внимание, что сервер nc не завершился и продолжает ожидать следующие порции данных.

Это явно можно увидеть, используя lsof.

Шаг 45. Запустите повторно UDP-клиент:

$ ./udp_client1

Была ли осуществлена передача данных клиентом? Увидел ли передачу данных сниффер? Получил и отобразил ли полученные данные сервер? Почему данные не дошли до сервера?

Шаг 46. Скомпилируйте UDP-сервер (см. [1, 2]):

$ gcc udp_server1.c -o udp_server1

Запустите UDP-сервер и UDP-клиент. Передал ли клиент серверу сообщение?

$ ./udp_server1

$ ./udp_client1

Шаг 47. Обратите внимание, что сервер продолжает ждать подключения. Запустите UDP-клиент ещё раз.

Была ли осуществлена передача данных клиентом? Увидел ли передачу данных сниффер? Получил и отобразил ли полученные данные сервер? Почему данные дошли до сервера? Почему не повторяется ситуация, возникшая на шаге 43?

Шаг 48. Поэкспериментируйте с кодом программ на Cи, сделайте доработки, предложенные ранее.

Подключите к экспериментам соседние компьютеры и их пользователей. Организуйте обмен трафиком по локальной сети.

Может ли UDP-клиент соединиться с TCP-сервером и передать данные? А наоборот? А если проверить экспериментально?

Если увеличить значение размера массива buf в использовавшихся программах на Cи и перекомпилировать их, то какого максимального размера можно осуществить передачу данных на практике? Какие будут ограничения, и чем они будут вызваны?

Шаг 49. Увеличиваются ли значения счётчиков iptables? Создайте правила и посмотрите, считается ли с помощью них проходящий между клиентом и сервером трафик?

# iptables -L -v -x -n

# iptables -I INPUT -p udp -s 127.0.0.1

Шаг 50. Запустите сниффер WireShark Network Analyzer и самостоятельно проведите несколько экспериментов.

Чем удобнее пользоваться графической средой или консолью?

Подготовьте отчёт, где отразите проделанные шаги. Какие практические моменты для вас оказались существенно новыми или неожиданными при работе с сокетами? Были ли расхождения теории с практикой во время проведения экспериментов, которые вы впоследствии не смогли объяснить?

В результате выполнения заданий вы получили практические навыки работы с сокетами с помощью стандартных средств ОС Linux, а также имели возможность скомпилировать код программ на Си и проверить его работоспособность.

  1. Закляков В. Лабораторная работа: Исследуем сокеты. Часть 1. // «Системный администратор», №4, 2016 г. – С. 75-79 (http://samag.ru/archive/article/3179).
  2. Закляков В. Лабораторная работа: Исследуем сокеты. Часть 2 (продолжение). // «Системный администратор», №5, 2016 г. – С. 67-71 (http://samag.ru/archive/article/3199).
  3. UNIX: разработка сетевых приложений /У. Стивенс. – СПб.: «Питер», 2003. – 1088 с. ISBN 5-318-00535-7.
  4. Описание ошибки Bind: Address Already in Use – http://hea-www.harvard.edu/~fine/Tech/addrinuse.html.

Комментарии отсутствуют

Добавить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

               Copyright © Системный администратор

Яндекс.Метрика
Tel.: (499) 277-12-45
E-mail: sa@samag.ru