(c) Larry Ewing, Simon Budig, Garrett LeSage
с 1994 г.

Кафедра Информатики и Математического Обеспечения

ПетрГУ | ИМиИТ | О кафедре | Проекты | Лаборатория ИТС | Семинары НФИ/AMICT
Сотрудники | Учебный процесс | Табель-календарь | Курсовые и выпускные работы
Вычислительные ресурсы | Публикации | Архив новостей | Контактная информация (English)

Компьютерные сети 2018, задачи

1. getaddrinfo(), inet_ntop(), ntohs()

1.1 Порядок байт, strtol()

Написать программу, которая получает один обязательный аргумент командной строки - беззнаковое целое 32-битное число, записывает его в переменную, и затем выводит содержимое ячеек памяти, в которых хранится эта переменная (в порядке возрастания адресов).

1.2 Порядок байт, strtol(), htonl()

Добавить к предыдущей программе преобразование полученного числа в сетевой порядок байт. Вывести результат (также в порядке возрастания адресов). Сравнить с выводом предыдущей программы.

1.3 Порядок байт, strtol(), htonl(), inet_ntop()

Добавить к предыдущей программе преобразование полученного числа с сетевым порядком байт в презентационный формат (строка) для AF_INET (IPv4) и вывод получившейся строки

>./a.out 0x01020304
host byte order:
s_addr=0x01020304, 0x04:0x03:0x02:0x01
network byte order:
s_addr=0x04030201, 0x01:0x02:0x03:0x04
s=1.2.3.4

1.4 getaddrinfo(), IPv4

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

1.5 getaddrinfo(), IPv4, IPv6

Модифицировать программу из п. 1.4 так, чтобы она выдавала еще и IPv6-адреса.

1.6 getaddrinfo(), IPv4, IPv6, номер порта

Модифицировать программу из п. 1.5 так, чтобы она получала два обязательных аргумента командной строки - доменное имя и имя сервиса и выдавала вместе с IPv4 или IPv6 адресами номер порта для подключения

Можно использовать task1.c как образец для задач 1.4-1.6

2. getnameinfo(), inet_pton()

2.1 inet_pton()

Написать программу, которая получает один обязательный аргумент командной строки - IPv4 адрес в строковом формате (aaa.bbb.ccc.ddd) и с помощью функции inet_pton() преобразует адрес во внутреннее представление. Вывести результат (можно использовать код из п.1.2)

2.2 inet_pton(), getnameinfo()

Добавить к программе из п.2.1 получение доменного имени для получившегося адреса с помощью функции getnameinfo(), вывести доменное имя (если есть).

2.3 inet_pton(), getnameinfo()

Модифицировать программу из п.2.3 так, чтобы она получала два обязательных аргумента командной строки - IPv4 адрес в строковом формате и номер порта, с помощью функции getnameinfo() получить доменное имя и имя сервиса, вывести (если есть).

3. Установка исходящего TCP-соединения

3.1 struct addrinfo *hints

Добавить к программе из п.1.6 ограничение на поиск адресов: искать только IPv4 и TCP

3.2 ai_family, ai_socktype, ai_protocol, socket()

Добавить к предыдущей программе создание сокета для первого найденного функцией getaddrinfo() значения

3.3 socket(), connect()

Добавить к предыдущей программе установку исходящего TCP-соединения на адрес из первого найденного функцией getaddrinfo() значения

3.4 socket(), connect(), write() или send()

Добавить к предыдущей программе отправку простейшего HTTP/1.0 запроса (GET /)

3.5 socket(), connect(), read() или recv()

Добавить к предыдущей программе копирование ответа удаленной стороны на стандартный вывод

> netcat -vv ya.ru 80
Connection to ya.ru 80 port [tcp/http] succeeded!
GET / HTTP/1.0
Host: ya.ru

HTTP/1.1 302 Found
Date: Tue, 20 Feb 2018 07:17:25 GMT
Cache-Control: no-cache,no-store,max-age=0,must-revalidate
Location: https://ya.ru/
Expires: Tue, 20 Feb 2018 07:17:26 GMT
Last-Modified: Tue, 20 Feb 2018 07:17:26 GMT
P3P: policyref="/w3c/p3p.xml", CP="NON DSP ADM DEV PSD IVDo OUR IND STP PHY PRE NAV UNI"
Set-Cookie: yandexuid=9922938791519111045; Expires=Fri, 18-Feb-2028 07:17:25 GMT; Domain=.ya.ru; Path=/
X-Content-Type-Options: nosniff
Content-Length: 0

3.6 socket(), connect(), getsockname()

Добавить к предыдущей программе получение адреса, автоматически назначенного локальному сокету, с помощью функции getsockname(), и вывод его в строковом формате

4. Передача данных по UDP

4.1 struct addrinfo *hints

Модифицировать программу из п.3.1: искать только IPv4 и UDP

4.2 ai_family, ai_socktype, ai_protocol, socket()

Добавить к предыдущей программе создание сокета для первого найденного функцией getaddrinfo() значения

4.3 socket(), sendto(), recvfrom()

Добавить к предыдущей программе отправку произвольной строки на первый адрес, найденный getaddrinfo(), и получение ответа. Для тестирования используйте echo-сервер на kappa.cs.prv

> echo qwerty | netcat -q -u kappa.cs.petrsu.ru echo
qwerty

4.4 socket(), connect(), send(), recv()

Модифицировать программу из п.4.2: сохранить первый адрес, найденный функцией getaddrinfo(), с помощью connect(), затем отправлять данные с помощью функции send().

5. UDP: socket(), recvfrom()

5.1. strtol() или getaddrinfo(), socket(), bind(), recvfrom()

Написать программу, которая получает один обязательный аргумент командной строки - номер порта. Далее нужно создать UDP-сокет, назначить ему полученный номер порта с помощью функции bind(), принимать данные через созданный сокет и копировать их на стандартный вывод программы

5.2. getnameinfo()

Добавьте к предыдущей программе вывод адреса удаленного сокета, с которого пришло сообщение

5.3. getnameinfo(), sendto()

Модифицируйте программу из п.5.2 так, чтобы полученные данные отправлялись обратно отправителю (в результате должен получиться свой UDP echo-сервер).

5.4 connect()

Модифицируйте программу из п.5.1: добавьте два обязательных параметра командной строки: имя и номер порта, с которых принимать сообщения. После создания сокета установите для него указанный адрес удаленного сокета с помощью функции connect(). Покажите, что после этого сообщения с других адресов не принимаются.

Для тестирования можно использовать утилиту netcat или программу из п.4 (указав свой номер порта)

> netcat -u -s 127.0.0.1 -p 3333 127.0.0.1 2222
qwerty
qwerty

6. TCP: прием одного входящего соединения.

6.1. strtol() или getaddrinfo(), socket(), bind(), listen(), accept().

Написать программу, которая получает один обязательный аргумент командной строки - номер порта. Далее нужно создать TCP-сокет, назначить ему полученный номер порта с помощью функции bind(), включить прием входящих соединений с помощью функции listen() и принять одно входящее соединение с помощью accept().

6.2. getpeername(), getnameinfo()

Добавьте к предыдущей программе вывод адреса удаленного сокета, с которого пришло сообщение

6.3. send() или write()

Модифицируйте программу из п.6.2 так, чтобы полученные данные отправлялись обратно отправителю (в результате должен получиться свой TCP echo-сервер).

Для тестирования можно использовать утилиты netcat или telnet

7. Прием и обработка нескольких входящих TCP-соединений

7.1 TCP с fork()

Модифицируйте программу из п.6.3 таким образом, чтобы для каждого установленного соединения порождался новый процесс с echo-сервером. После закрытия соединения порожденный процесс должен корректно завершаться (не оставаться в состоянии zombie).

7.2 TCP с select()

Модифицируйте программу из п.6.3 таким образом, чтобы все установленные соединения обрабатывались с помощью мультиплексирования ввода-вывода (функция select() или аналоги). Для передачи ответа тоже должно использоваться мультиплексирование ввода-вывода (функция select() или аналоги).