Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
download_and_use_it.docx
Скачиваний:
4
Добавлен:
29.07.2019
Размер:
176.01 Кб
Скачать

1.5 Таймер 2msl

Состояние ВРЕМЯ_ОЖИДАНИЯ (TIME_WAIT) также иногда называется состоянием ожидания 2MSL. В каждой реализации выбирается значение для максимального времени жизни сегмента (MSL - maximum segment lifetime) . Это максимальное время, в течение которого сегмент может существовать в сети, перед тем как он будет отброшен. Мы знаем, что это время ограничено, так как TCP сегменты передаются посредством IP датаграмм, а каждая IP датаграмма имеет поле TTL, которое ограничивает время ее жизни.

При использовании MSL действуют следующие правила: когда TCP осуществляет активное закрытие и посылает последний сегмент содержащий подтверждение (ACK), соединение должно остаться в состоянии TIME_WAIT на время равное двум MSL. Это позволяет TCP повторно послать последний ACK в том случае, если первый ACK потерян (в этом случае удаленная сторона отработает тайм-аут и повторно передаст свой конечный FIN).

Другое назначение ожидания 2MSL заключается в том, что пока TCP соединение находится в ожидании 2MSL, пара сокетов, выделенная для этого соединения (IP адрес клиента, номер порта клиента, IP адрес сервера и номер порта сервера), не может быть повторно использована. Это соединение может быть использовано повторно только когда истечет время ожидания 2MSL.

К сожалению, большинство реализаций (Berkeley одна из них) подчиняются более жестким требованиям. По умолчанию локальный номер порта не может быть повторно использован, до тех пор пока этот номер порта является локальным номером порта пары сокетов, который находится в состоянии ожидания 2MSL.

Некоторые реализации и API предоставляют средства, которые позволяют обойти эти ограничения. С использованием API сокет может быть указана опция сокета SO_REUSEADDR. Она позволяет вызывающему назначить себе номер локального порта, который находится в состоянии 2MSL, однако правила TCP не позволяют этому номеру порта быть использованным в соединении, которое находится в состоянии ожидания 2MSL.

Каждый задержанный сегмент, прибывающий по соединению, которое находится в состоянии ожидания 2MSL, отбрасывается. Так как соединение определяется парой сокет в состоянии 2MSL, это соединение не может быть повторно использовано до того момента, пока мы не сможем установить новое соединение. Это делается для того, чтобы опоздавшие пакеты не были восприняты как часть нового соединения. (Соединение определяется парой сокет. Новое соединение называется восстановлением или оживлением данного соединения.)

Обычно клиент осуществляет активное закрытие и входит в режим TIME_WAIT. Сервер обычно осуществляет пассивное закрытие и не проходит через режим TIME_WAIT. Можно сделать вывод, что если мы выключим клиента и немедленно его перестартуем, этот новый клиент не сможет использовать тот же самый локальный номер порта. В этом нет никакой проблемы, так как клиенты обычно используют динамически назначаемые порты и не заботятся, какой динамически назначаемый порт используется в настоящее время. Однако, с точки зрения сервера все иначе, так как сервера используют заранее известные порты. Если мы выключим сервер, который имеет установленное соединение, и постараемся немедленно перестартовать его, сервер не может использовать свой заранее известный номер порта в качестве конечной точки соединения, так как этот номер порта является частью соединения, находящегося в состоянии ожидания 2MSL. Поэтому может потребоваться от 1 до 4 минут, перед тем как сервер будет перестартован.

2 Разработка технологии проведения исследований

2.1 Общие сведения

При исследовании всех четырёх таймеров TCP протокола, клиент будет запускаться на операционной системе Linux Mint 12, сервер запускается на операционной системе UBUNTU 10.04, которая установлена на Oracle VirtualBox. VirtualBox, в свою очередь, установлен на Linux Mint 12.

Для просмотра передаваемых пакетов по TCP протоколу, используется утилита tcpdump.

В качестве клиента и сервера, при исследовании таймеров, таких, как устойчивый таймер, таймер "оставайся в живых", таймер 2MSL, будет выступать программа sock, которая, с помощью передаваемых ей аргументов, может работать в режиме, как сервера, так и клиента.

2.2 Таймер повторной передачи

Для проведения исследования таймера повторной передачи, используется следующий алгоритм:

1 – сервер регистрируется в сети. Выполняется командой java TCPServer

2 – подключается клиент к серверу. Выполнятся команда java Client host, где host – ip-адрес сервера

3 – клиент обменивается с сервером сообщениями для того, чтобы убедится, что соединение работает. Для этого вводятся любые символы со стороны клиента в программе Client, и со стороны сервера в программе TCPServer поочерёдно.

4 – сервер отключается от сети: отсоединяется сетевой кабель от сервера, чтобы сервер не послал пакеты о завершении своей работы, а клиент продолжал думать, что сервер все ещё работает. Для этого отключаем активное сетевое подключение в VirtualBox.

5 – клиент отсылает сообщение на сервер. Отправляется любые символы в программе Client.

6 – производится наблюдение за повторными передачами пакета. Используется утилита tcpdump. Ожидается, что повторных передач пакета будет более одной, и время между повторными передачами будет увеличиваться. Значение таймера повторной передачи определяется, как промежуток времени между повторными передачами пакета.

2.3Устойчивый таймер TCP

Для проведения исследования устойчивого таймера TCP, учитывается, что рассматриваемый таймер должен срабатывать, когда принимающая пакет сторона объявляет размер окна равным нулю. Построим следующий алгоритм исследования:

1 – запускается принимающий процесс, который ожидает прихода запроса на соединение от клиента, принимает запрос на соединение, а затем надолго засыпает перед тем, как начать чтение из сети. Выполняется команда sock -is -Pn port, где n – количество ожидаемых сервером миллисекунд, port – номер порта.

2 – запускается клиент, который будет передавать данные принимающему процессу. Выполняем команду sock -i -n100 -w4096 host port, где host – ip-адрес сервера, port – порт сервера.

3 – производится наблюдение за передачей пакетов. Ожидается, что после ухода принимающего процесса в состояние ожидания, клиент будет производить пробы окна по истечению 500мс на устойчивом таймере, после получения сообщения от сервера с параметром размера окно win=0, до того момента, пока не получит сообщения с параметром размера окна win > 0. Так же ожидается, что после каждой отправки пробы окна, значение таймера будет увеличиватся.

4 – значение устойчивого таймера определяется как промежуток времени между пробами окна.

5 – после истечения заданного интервала ожидания, ожидается передача данных клиентом на сервер(принимающий процесс).

2.4 Таймер «оставайся в живых»

Обозначается конец, на котором включается опция "оставайся в живых" – сервером, а другой конец – клиентом. Хост клиента включен и доступен для сервера. TCP клиент откликается нормально, и сервер знает, что удаленный конец все еще включен. TCP сервер перезапустит таймер "оставайся в живых" еще на 2 часа. Если до истечения следующих 2 часов по соединению будет осуществлен какой-либо обмен, таймер снова сбросится и установится в 2 часа. Алгоритм проведения исследования будет следующим:

1 – включается сервер с опцией "оставайся в живых". Выполняется команда sock -K -s -v port. Параметр –К включает опцию "оставайся в живых".

2 – запускается клиент. Выполняется команда sock -v host port

3 – производится обмен сообщениями между сервером и клиентом, чтобы убедится, что соединение работает, и сбросить таймер "оставайся в живых".

4 – в течении более четырёх часов не отсылаются сообщения между клиентом и сервером

5 – производится наблюдение за пакетами подтверждения соединения по истечению каждых 2-х часов.

6 – отключается кабель от сервера. Для этого отключаем активное сетевое подключение в VirtualBox. Ожидается, что при следующей отсылке пакета "оставайся в живых", не получив пакет подтверждения, сервер должен определить, что соединение разорвано.

2.5 Таймер 2MSL

В отличии от клиентов, которые обычно используют динамически назначаемые порты, сервера используют заранее известные порты. Если мы выключим сервер, который имеет установленное соединение, и постараемся немедленно перестартовать его, сервер не может использовать свой заранее известный номер порта в качестве конечной точки соединения, так как этот номер порта является частью соединения, находящегося в состоянии ожидания 2MSL. Поэтому может потребоваться от 1 до 4 минут, перед тем как сервер будет перестартован.

Для исследования таймера 2MSL воспользуемся следующим алгоритмом:

1 – запускается сервер. Выполняется команда sock -v -s port

2 – запускается клиент, который подключается к серверу. Выполняется команда sock -v host port.

3 – на сервере вводится символ выключения, чтобы корректно выключить сервер.

4 – запускается таймер, и регистрируется время попытки перезапуска сервера на том порту, на котором сервер работал до выключения

5 – MSL будет равно половине отрезка времени от выключения сервера до его повторного запуска.

6 – повторно запускается клиент командой sock -v host port.

7 – вводится символ выключения на клиенте, чтобы отключить клиент.

8 – запускается таймер, и регистрируем время попытки перезапуска клиент на том порту, на котором клиент работал до выключения. Выполняются команды sock -bClientPort -v hostServer portServer, где ClientPort – порт, на котором был запущен клиент до его отключения.

9 – определяется MSL, аналогично пункту 5. Ожидается, что MSL на сервере будет равно MSL на клиенте, при условии одинаковых платформ операционных систем клиента и сервера.

3 Разработка средств решения поставленной задачи

Для исследования таймера повторной передачи, были написаны клиент и сервер на языке программирования Java, которые смогут обмениваться текстовыми сообщениями по TCP протоколу. Программный код клиента представлен в листинге 1, программный код сервера представлен в листинге 2.

Листинг 1 – программный код клиента Client.java

import java.io.*;

import java.net.*;

/**

* TCP message client

* @author Anton Lyashenko

*/

public class Client {

public static void main(String[] args) {

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

PrintStream out = System.out;

try {

Socket c = new Socket(args[0], 8888);

printSocketInfo(c);

BufferedWriter w = new BufferedWriter(new OutputStreamWriter(c.getOutputStream()));

BufferedReader r = new BufferedReader(new InputStreamReader(c.getInputStream()));

String m = null;

while ((m = r.readLine()) != null) {

out.println(m);

m = "Client: " + in.readLine();

w.write(m, 0, m.length());

w.newLine();

w.flush();

}

w.close();

r.close();

c.close();

} catch (IOException e) {

System.err.println(e.toString());

}

}

private static void printSocketInfo(Socket s) {

System.out.println("Remote address = " + s.getInetAddress().toString());

System.out.println("Remote port = " + s.getPort());

System.out.println("Local socket address = " + s.getLocalSocketAddress().toString());

System.out.println("Local address = " + s.getLocalAddress().toString());

System.out.println("Local port = " + s.getLocalPort());

}

}

Листинг 2 – программный код сервера Server.java

import java.util.Random;

import java.io.*;

import java.net.*;

/**

* TCP message server

* @author Anton Lyashenko

*/

public class Server extends Thread {

public void run() {

Random randomGenerator = new Random();

int randomInt = randomGenerator.nextInt(6);

System.out.println(randomInt);

}

public static void main(String[] args) {

try {

ServerSocket s = new ServerSocket(8888);

printServerSocketInfo(s);

Socket c = s.accept();

printSocketInfo(c);

BufferedWriter w = new BufferedWriter(new OutputStreamWriter(c.getOutputStream()));

BufferedReader r = new BufferedReader(new InputStreamReader(c.getInputStream()));

String m = "Welcome to Reverse Echo Server." + " Please type in some words.";

w.write(m, 0, m.length());

w.newLine();

w.flush();

Server mythr = new Server();

mythr.start();

while ((m = r.readLine()) != null) {

System.out.println("Client: " + m);

BufferedReader mybr = new BufferedReader(new InputStreamReader(System.in));

String mystr = "Server: " + mybr.readLine();

w.write(mystr, 0, mystr.length());

w.newLine();

w.flush();

}

w.close();

r.close();

c.close();

s.close();

} catch (IOException e) {

System.err.println(e.toString());

}

}

private static void printSocketInfo(Socket s) {

System.out.println("Remote address = " + s.getInetAddress().toString());

System.out.println("Remote port = " + s.getPort());

System.out.println("Local socket address = " + s.getLocalSocketAddress().toString());

System.out.println("Local address = " + s.getLocalAddress().toString());

System.out.println("Local port = " + s.getLocalPort());

}

private static void printServerSocketInfo(ServerSocket s) {

System.out.println("Server socker address = " + s.getInetAddress().toString());

System.out.println("Server socker port = " + s.getLocalPort());

}

}

4 Исследование модели и анализ результатов

4.1 Исследование таймера повторной передачи

Выполненные действия, в соответствии с поставленным алгоритмом (п. 2.1), и результаты исследования, включая подробные комментарии, приведены в листинге 3.

Листинг 3 – исследование таймера повторных передач.

//запускаем сервер

anton@ubuntu:~/Chat$ java TCPServer

Server socker address = 0.0.0.0/0.0.0.0

Server socker port = 8888

//клиент подключился к серверу

Remote address = /192.168.1.3

Remote port = 39876

Local socket address = /192.168.1.2:8888

Local address = /192.168.1.2

Local port = 8888

5

//убеждаемся в работе соединения, получая сообщения от клиента и посылая ему //ответы

Client: message1

message2

Client: message3

message4

//после отправки сообщения message4 отключаем сетевой кабель

//запуск клиента

anton@anton-HP-Pavilion-dv6-Notebook-PC ~/TCPIP_Chat $ java Client 192.168.1.2

Remote address = /192.168.1.2

Remote port = 8888

Local socket address = /192.168.1.3:39876

Local address = /192.168.1.3

Local port = 39876

Welcome to Reverse Echo Server. Please type in some words.

//убеждаемся в работе соединения, передавая сообщения на сервер и получая

//ответы

message1

Server: message2

message3

Server: message4

//посылаем сообщение на сервер после того, как отключили сетевой кабель от //сервера

message5

//запускаем утилиту tcpdump

anton@anton-HP-Pavilion-dv6-Notebook-PC ~ $ sudo tcpdump tcp -i wlan0 -vv

tcpdump: listening on wlan0, link-type EN10MB (Ethernet), capture size 65535 bytes

//анализируем вывод утилиты tcpdump

//устанавливается соединение клиента с сервером

00:23:43.783562 IP (tos 0x0, ttl 64, id 1747, offset 0, flags [DF], proto TCP (6), length 60)

anton-HP-Pavilion-dv6-Notebook-PC.local.39876 > ubuntu.local.8888: Flags [S], cksum 0x8384 (incorrect -> 0x5ef9), seq 3574321117, win 14600, options [mss 1460,sackOK,TS val 3655950 ecr 0,nop,wscale 4], length 0

00:23:43.784292 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)

ubuntu.local.8888 > anton-HP-Pavilion-dv6-Notebook-PC.local.39876: Flags [S.], cksum 0x2bd0 (correct), seq 2658115748, ack 3574321118, win 5792, options [mss 1460,sackOK,TS val 595553 ecr 3655950,nop,wscale 6], length 0

//обмен сообщениями

00:23:43.784339 IP (tos 0x0, ttl 64, id 1748, offset 0, flags [DF], proto TCP (6), length 52)

anton-HP-Pavilion-dv6-Notebook-PC.local.39876 > ubuntu.local.8888: Flags [.], cksum 0x837c (incorrect -> 0x6daa), seq 1, ack 1, win 913, options [nop,nop,TS val 3655950 ecr 595553], length 0

00:23:43.789563 IP (tos 0x0, ttl 64, id 46788, offset 0, flags [DF], proto TCP (6), length 111)

ubuntu.local.8888 > anton-HP-Pavilion-dv6-Notebook-PC.local.39876: Flags [P.], cksum 0xcb4f (correct), seq 1:60, ack 1, win 91, options [nop,nop,TS val 595554 ecr 3655950], length 59

00:23:43.789660 IP (tos 0x0, ttl 64, id 1749, offset 0, flags [DF], proto TCP (6), length 52)

anton-HP-Pavilion-dv6-Notebook-PC.local.39876 > ubuntu.local.8888: Flags [.], cksum 0x837c (incorrect -> 0x6d6d), seq 1, ack 60, win 913, options [nop,nop,TS val 3655951 ecr 595554], length 0

00:24:08.385325 IP (tos 0x0, ttl 64, id 1750, offset 0, flags [DF], proto TCP (6), length 69)

anton-HP-Pavilion-dv6-Notebook-PC.local.39876 > ubuntu.local.8888: Flags [P.], cksum 0x4a77 (correct), seq 1:18, ack 60, win 913, options [nop,nop,TS val 3662100 ecr 595554], length 17

00:24:08.386107 IP (tos 0x0, ttl 64, id 46789, offset 0, flags [DF], proto TCP (6), length 52)

ubuntu.local.8888 > anton-HP-Pavilion-dv6-Notebook-PC.local.39876: Flags [.], cksum 0x4087 (correct), seq 60, ack 18, win 91, options [nop,nop,TS val 601704 ecr 3662100], length 0

00:24:24.284387 IP (tos 0x0, ttl 64, id 46790, offset 0, flags [DF], proto TCP (6), length 69)

ubuntu.local.8888 > anton-HP-Pavilion-dv6-Notebook-PC.local.39876: Flags [P.], cksum 0x1606 (correct), seq 60:77, ack 18, win 91, options [nop,nop,TS val 605679 ecr 3662100], length 17

00:24:24.284441 IP (tos 0x0, ttl 64, id 1751, offset 0, flags [DF], proto TCP (6), length 52)

anton-HP-Pavilion-dv6-Notebook-PC.local.39876 > ubuntu.local.8888: Flags [.], cksum 0x837c (incorrect -> 0x1e32), seq 18, ack 77, win 913, options [nop,nop,TS val 3666075 ecr 605679], length 0

00:24:32.582451 IP (tos 0x0, ttl 64, id 1752, offset 0, flags [DF], proto TCP (6), length 69)

anton-HP-Pavilion-dv6-Notebook-PC.local.39876 > ubuntu.local.8888: Flags [P.], cksum 0x0b25 (correct), seq 18:35, ack 77, win 913, options [nop,nop,TS val 3668149 ecr 605679], length 17

00:24:32.583167 IP (tos 0x0, ttl 64, id 46791, offset 0, flags [DF], proto TCP (6), length 52)

ubuntu.local.8888 > anton-HP-Pavilion-dv6-Notebook-PC.local.39876: Flags [.], cksum 0x1123 (correct), seq 77, ack 35, win 91, options [nop,nop,TS val 607753 ecr 3668149], length 0

00:24:39.644538 IP (tos 0x0, ttl 64, id 46792, offset 0, flags [DF], proto TCP (6), length 69)

ubuntu.local.8888 > anton-HP-Pavilion-dv6-Notebook-PC.local.39876: Flags [P.], cksum 0xef40 (correct), seq 77:94, ack 35, win 91, options [nop,nop,TS val 609519 ecr 3668149], length 17

00:24:39.644588 IP (tos 0x0, ttl 64, id 1753, offset 0, flags [DF], proto TCP (6), length 52)

anton-HP-Pavilion-dv6-Notebook-PC.local.39876 > ubuntu.local.8888: Flags [.], cksum 0x837c (incorrect -> 0x0010), seq 35, ack 94, win 913, options [nop,nop,TS val 3669915 ecr 609519], length 0

//после передачи пакета в 00:24:39.644588 от сервера отключаем сетевой кабель

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

00:25:07.046486 IP (tos 0x0, ttl 64, id 1754, offset 0, flags [DF], proto TCP (6), length 69)

anton-HP-Pavilion-dv6-Notebook-PC.local.39876 > ubuntu.local.8888: Flags [P.], cksum 0xda58 (correct), seq 35:52, ack 94, win 913, options [nop,nop,TS val 3676765 ecr 609519], length 17

00:25:07.250894 IP (tos 0x0, ttl 64, id 1755, offset 0, flags [DF], proto TCP (6), length 69)

anton-HP-Pavilion-dv6-Notebook-PC.local.39876 > ubuntu.local.8888: Flags [P.], cksum 0xda24 (correct), seq 35:52, ack 94, win 913, options [nop,nop,TS val 3676817 ecr 609519], length 17

00:25:07.666886 IP (tos 0x0, ttl 64, id 1756, offset 0, flags [DF], proto TCP (6), length 69)

anton-HP-Pavilion-dv6-Notebook-PC.local.39876 > ubuntu.local.8888: Flags [P.], cksum 0xd9bc (correct), seq 35:52, ack 94, win 913, options [nop,nop,TS val 3676921 ecr 609519], length 17

00:25:08.498892 IP (tos 0x0, ttl 64, id 1757, offset 0, flags [DF], proto TCP (6), length 69)

anton-HP-Pavilion-dv6-Notebook-PC.local.39876 > ubuntu.local.8888: Flags [P.], cksum 0xd8ec (correct), seq 35:52, ack 94, win 913, options [nop,nop,TS val 3677129 ecr 609519], length 17

00:25:10.166898 IP (tos 0x0, ttl 64, id 1758, offset 0, flags [DF], proto TCP (6), length 69)

anton-HP-Pavilion-dv6-Notebook-PC.local.39876 > ubuntu.local.8888: Flags [P.], cksum 0xd74b (correct), seq 35:52, ack 94, win 913, options [nop,nop,TS val 3677546 ecr 609519], length 17

00:25:13.502895 IP (tos 0x0, ttl 64, id 1759, offset 0, flags [DF], proto TCP (6), length 69)

anton-HP-Pavilion-dv6-Notebook-PC.local.39876 > ubuntu.local.8888: Flags [P.], cksum 0xd409 (correct), seq 35:52, ack 94, win 913, options [nop,nop,TS val 3678380 ecr 609519], length 17

Проанализируем повторную передачу пакета. В данном эксперименте ожидание пакетов повторной передачи заняло 10 минут, однако после отправки пакета в момент времени 00:25:13.502895 больше пакетов отослано не было. Всего клиентом на повторную передачу пакета было сделано 6 попыток. Расчеты значения таймера повторной передачи приведены в таблице 1.

Таблица 1 – значения таймера повторной передачи

№ попытки

1

2

3

4

5

6

Время передачи

00:25:07.046486

00:25:07.250894

00:25:07.666886

00:25:08.498892

00:25:10.166898

00:25:13.502895

Значение таймера (RTO), с

0.204408

0.415992

0.832006

1.668006

3.335997

Не определено

Заключение: значение RTO после каждой попытки повторной передачи увеличивалось приблизительно в 2 раза, что соответствует рекомендуемому значению коэффициента β в формуле (1.2). Результаты эксперимента соответствуют поставленным ожиданиям.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]