Что вы знаете о tcp как о внешнем интерфейсе?

TCP/IP

Как много вы знаете о tcp

В группе интервьюеров переднего плана часто встречается, что кто-то встречается с интервьюером, чтобы спросить рукопожатие и волну tcp, например, знаете ли вы tcp, объясните трехстороннее рукопожатие и четырехстороннюю волну tcp, я думаю, если вы просто понимаете эти два Вопроса, действительно ли они имеют такое значение? Поэтому постарайтесь больше узнать о содержании сетевого общения.Помню,когда я был в своей компании,один старик сказал,что сетевое общение на самом деле очень важно.Ведь мы в основном в Интернете,будем ли мы работать или жить , тем более, что разработчик в основном имеет дело с HTTP-запросами каждый день, поэтому необходимо понимать принцип передачи по сети.Давайте немного подробнее рассмотрим содержание передачи по сети.

base

Сетевой уровень OSI (Open Systems Interconnection, Open Systems Interconnection)

Сверху вниз расположены:

7. Прикладной уровень (Приложение)
6. Уровень представления
5. Сеансовый уровень (Session)
4. Транспортный уровень (Транспорт)
3. Сетевой уровень (Сеть) -- маршрутизатор
2. Уровень канала передачи данных (канал передачи данных) -- переключатель
1. Физический уровень (Physical) -- сетевая карта, концентратор (Hub)

Основное содержание объяснено не слишком много, при необходимости можноВыйти и повернуть направохорошо Сегодня мы в основном сосредоточимся на содержимом слоя tcp. Если вам интересно, я предлагаю вам выполнить шаги, чтобы увидеть реальную операцию. Во-первых, мы представим инструмент wireshark, который может помочь нам захватить tcp и снизить пакеты -level.здесь, После открытия происходит загрузка, просто скачайте то, что может использовать ваша система, и установите его полностью, пока все не будет завершено.Далее мы начнем фактический захват пакета.

захват пакетов

я использовал здесьДомашняя страница BaiduПроведите эксперимент по захвату пакетов, сначала установите фильтр

Вы можете выбрать между http и tcp или только tcp

Затем перейдите в консоль, чтобы пропинговать IP-адрес домашней страницы Baidu.

хорошо, см. IP-адрес 180.97.33.108

Затем мы идем к wireshark, чтобы установить запрос ip

Откройте домашнюю страницу Baidu в Chrome, затем вы можете увидеть информацию о передаче TCP.

Контента еще немного, давайте посмотрим на процесс передачи контента по tcp

tcp base

Сначала посмотрите на структуру пакета заголовка tcp.1. Уровень протокола tcp не заботится об ip.Конкретное местоположение ip определяется уровнем ip, но уровень tcp должен определить номер порта, поэтому он будет нести информацию о порте источника и назначения, чтобы соответствующий порт номер можно найти;

2.sequence numberНа практике используется серийный номер SEQ.Этот серийный номер играет очень важную роль.Все мы знаем, что самая большая разница между tcp и udp заключается в том, что tcp является стабильным и упорядоченным, а seq может гарантировать порядок.Когда A отправляет пакет данных на B, последовательность будет наложена, и каждый передатчик будет приносить эту информацию при передаче данных, а другой конец может сортировать порядок полученной информации в соответствии с этим порядковым номером, и передача информации никогда не гарантировалась , Это правильно, и его также можно использовать для подтверждения потери пакетов; кроме того, следует отметить, что когда есть данные для отправки, seq будет следовать за порядковым номером в качестве источника, и он будет отправьте каждый байт для отправки.Данные пронумерованы, например, текущая последовательность = 10, размер пакета данных, который будет отправлен на этот раз, составляет 200 байт, затем последовательность = 210 будет обновлена ​​при фактической отправке, чтобы обеспечить порядок передаваемых данных;

3. Номер подтверждения, ACK, используемый на практике, является ответом с другого конца на последовательность другой стороны.Как правило, последовательность + 1, заданная другой стороной, будет добавлена ​​​​к следующему пакету, так что другая сторона будет знать, что мы получили предыдущую новость;

4.окно представляет собой скользящее окно, которое на самом деле представлено выигрышем. Размер выигрыша очень важен. Чем больше выигрыш, тем быстрее передача, потому что размер выигрыша напрямую определяет, сколько пакетов данных может быть отправлено за один раз. время до определенного конца без использования Ожидание ответа ACK другой стороны, но выигрыш будет уменьшаться с каждым отправленным пакетом (поясняется позже);

5. зарезервировано - очень важная роль в передаче tcp, бит флага, ответчик выполнит соответствующую операцию в соответствии с сигналом, данным другой стороной, например, бит флага FIN обычно используется при отключении;

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

Трёхстороннее рукопожатие (стук в доску)

Наблюдая за первыми несколькими передачами, мы можем сначала игнорировать тип TLS. Он обрабатывает зашифрованный контент ssl. Если вам интересно, вы можете пойти в Google самостоятельно. Сосредоточьтесь на первых трех tcp. Первый раз — это наш собственный ip на ip сервера Baidu. , Первый пакет отправлен, seq=0, начальный сигнал данных равен 0, win=65535 означает, что размер окна на моей стороне равен 65535, len=0 означает, что размер и длина пакета, который я хочу принять, равны 0, mss Это означает, что содержимое самого большого пакета, который может быть получен моей стороной в этой передаче, равно 1460 (нам пока не нужно заботиться об остальном). Давайте смоделируем разговор ниже:

A: B, привет, я A, прошу установить соединение, мой seq равен 0, мой выигрыш равен 65535, я надеюсь, что длина моего контента в этом ответе равна 0, и максимальный контент, который я могу получить на этот раз, составляет 1460 , более; B: A, как дела, я получил ваше сообщение, я B, мой seq на этот раз 0 (обратите внимание, что порядковые номера обеих сторон вычисляются независимо, и они все начинаются здесь с 0), я отвечу на ваш акк Это 1 (seq+1 of A означает, что я получил сообщение о том, что ваша последовательность равна 0), размер моего окна 8192, я надеюсь, что вы ответите на мой len этого сообщения также 0, максимальный ответ, который я могу получить здесь размер 1452, больше; A: Хорошо, я получил ваш ответ, последовательность, которую я отправил вам сейчас, равна 1 (последний раз был 0, на этот раз это 1), и я ответил, что ваш ack равен 1 (последовательность B+1), я Текущая размер окна 25984, и длина ответа, я надеюсь, 0, мы установили соединение, закончилось;

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

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

2 раза:

А: Эй, эй, я А, ты меня слышишь? Б: Я здесь, я слышу, я Б, ты меня слышишь? A: (Я слышал, я не хочу с тобой разговаривать) Б: Привет, привет? Не слышу? I X, другая сторона умерла, и я повесил трубку. .

4 раза:

А: Эй, эй, я А, ты меня слышишь? Б: Я здесь, я слышу, я Б, ты меня слышишь? А: Я слышал, а ты? Ты это слышишь? Б: ? ? Вы умственно отсталый? Разве я не говорил, что слышу тебя и не хочу говорить с хх. . .

Таким образом, наиболее разумным является 3 раза:

А: Эй, эй, я А, ты меня слышишь? Б: Я здесь, я слышу, я Б, ты меня слышишь? О: Я слышал. Пойдем сегодня на рыбалку. . балабала

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

помахал четыре раза

Мы знаем, что tcp-соединение полнодуплексное, и А и Б могут связываться друг с другом.Если вы не понимаете, то можете подумать о телефонном звонке (аналог, не воспринимайте всерьёз). совершение телефонного звонка является однодуплексным, потому что одновременно только один человек может говорить, а другой человек может слушать.Если два человека говорят вместе, никто не может четко слышать, что бессмысленно, но tcp является полнодуплексным, что то есть, пока А отправляет сообщение Б, Б тоже отправляет А А. Поэтому при разъединении необходимо знать обе стороны. Если знает только одна сторона, это точно не сработает. Поэтому при разъединении требуется следующее:

A: B, извините, мне нужно закрыть соединение здесь, вы готовы? (Отправляет сигнал плавника на B, ожидая ответа)

B: Хорошо, A, я получил ваш сигнал закрытия, у меня еще есть данные для отправки, вы ждете меня (ответьте на A, верните последнее сообщение ACK, если это не удается, вы можете отправить его повторно)

B: Брат А, я в порядке, я могу закрыть его, я скажу тебе в последний раз, и я закрою его, когда ты ответишь мне;

A: Хорошо, брат, позволь мне ответить тебе, закрой его, когда получишь, проигнорируй меня (после отправки этого сообщения войдите в состояние time_wait)

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

A: Дождавшись 2MSL (максимальное время выживания сегмента), B ничего не приходит, и я его тоже закрыл;

Все закончилось после 4 волн рук здесь, 2 вопроса:

1. Почему нужно три раза пожать руку и четыре раза помахать?

При рукопожатии A и B здороваются, B может напрямую передать свою SYN-информацию и ACK-информацию A, но при рукопожатии A говорит, что я собираюсь отключиться, B еще не закончил отправку последних данных, поэтому вам нужно сначала ответьте на A, я получил ваш запрос на отключение, но вам нужно подождать, пока я предоставлю вам окончательный контент, поэтому вот 2 шага: (1) Ответ на А; (2) Отправьте свои последние данные

2. Почему А должен ждать максимальное время выживания сегмента, прежде чем ввести TIME_WAIT перед закрытием?

Причина в том, что я беспокоюсь о потере пакетов, вызванной ненадежной сетью.Что, если последний ACK, отвечающий на B, будет потерян?В течение этого времени A может повторно отправить пакет, но если максимальное время ожидания превышено, даже если он не может быть получен. Он больше не работает, поэтому его можно закрыть.

Как понять роль раздвижных окон?

Из приведенного выше содержания у нас есть краткое представление о содержании трехстороннего рукопожатия и четырехкратной волны, а затем мы также знаем значение некоторых полей пакета, но сама сеть нестабильна, то есть, нет гарантии, что пакеты данных дойдут до противоположной стороны.Так как же tcp добиться стабильной и упорядоченной передачи за минимально возможное время?

Мы знаем, что информация SYN будет иметь свой собственный seq и серийный номер, что может гарантировать, что другая сторона знает, как сортировать после ее получения, но если передача должна быть синхронной, представьте, что когда A отправляет B, он должен дать B 1, 2 , 3, 4, 5 пакетов, после отправки 1 дождитесь подтверждения 1, затем отдайте 2, дождитесь подтверждения 2, максимальное время ожидания каждого tcp под linux2^5 - 1 = 63с (время повтора по умолчанию — 5 раз), потому что при отправке пакета ответ ACK не получен в течение определенного периода времени.Задержки: 1 секунда, 3 секунды, 7 секунд, 15 секунд, 31 секунда, из которых 31 с — это время 1 + 2 + 4 + 8 + 16 = 31 с для первых 5 попыток, а последние 32 с — время ожидания последней попытки. во-вторых), так что общее количество составляет 63 с. Если вы ждете один за другим, это слишком страшно, если сетевая среда относительно плохая, поэтому, чтобы избежать потери пакетов, минимизируйте потерю времени и введите концепцию раздвижное окно, окно

Поскольку окно определяется 16-разрядными битами TCP принимающей стороны, окно может обеспечить максимальный буфер размером 65535 байт. Фактически, это скользящее окно в основном используется для ограничения тока и буферизации. Выигрыш в каждой передаче TCP обеспечивает другой стороне. Когда A отправляет данные B, данные, которые превышают длину выигрыша B, будут отброшены. В то же время окно также может повысить эффективность отправки данных за счет поведения, аналогичного параллелизму, как показано на следующий рисунок:

Видно, что A отправил 3 порции данных в B подряд, но ACK в ответ на B не изменился, то есть все они ответили на один и тот же ответ от одного и того же B, но собственная последовательность A была обновляется 3 раза, сначала 1, затем 69 - это 1521 в конце, что указывает на то, что эти три пакета отправляются непрерывно.На самом деле, пока размер текущего пакета данных не превышает размер окна другой стороны, он может быть отправлено непрерывно, а затем увидеть:

Эти четыре пакета данных — это пакеты данных, на которые B ответил A. Вы можете видеть, что все они отвечают на пакеты данных, переданные A. Обратите внимание, что, поскольку A отправил несколько пакетов данных подряд, B может быть не в состоянии ответить сразу, поэтому B поместит эту информацию в буфер, но чем больше данных вы введете, тем меньше будет ваш буфер, что отражается в собственном выигрыше B. Мы видим, что выигрыш B продолжает становиться меньше, указывая на то, что он не был Перейдите к четвертому Когда сообщение было отправлено, мы увидели, что B выдал сообщение под названием WINDOW UPDATE и обнаружили, что выигрыш B стал больше, а это значит, что он обработал несколько последовательных пакетов данных, отправленных A ранее, а затем он будет обновляться снова.Размер выигрыша, следует отметить, что когда выигрыш на tcp-конце близок или равен 0, передача остановится, и передача не будет продолжаться до тех пор, пока обновление окна не обновит, что буфер был очищен.

Потеряли пакеты?

см. картинку ниже

Видно, что ACK непрерывно увеличивается.В соединении нельзя сказать, что сначала возвращается ACK=3922, а затем ACK=3913.В этом случае, когда другой конец получает 3922, он думает, что все предыдущие На самом деле еще не получено 3913. Следует отметить, что SeqNum и Ack основаны на количестве байтов, поэтому при подтверждении нельзя пропустить подтверждение, можно подтвердить только самый большой непрерывно полученный пакет. Затем рассмотрим следующую ситуацию: если A отправляет 5 пакетов с номерами 1, 2, 3, 4 и 5, B получает 1, Ack получает 2 (представляющих полученный 1), затем 2 потеряны, 3, 4 и 5 получены, может у тебя прямо ACK=6? Конечно нет, в этом случае tcp нестабилен, рассмотрим 2 варианта повторной передачи по таймауту:

1. Повторно передавать только 2 после тайм-аута; 2. Дайте 2, 3, 4, 5 снова после тайм-аута;

Эти две схемы хороши и плохи, первая медленная, а вторая тратит впустую полосу пропускания, поэтому tcp вводит быстрый механизм повторной попытки тайм-аута (алгоритм быстрой повторной передачи), который не рассчитывается по времени, а управляется данными для повторной передачи. пакеты не приходят непрерывно, например, приходит 1, не приходит 2, также приходят 3, 4 и 5. В это время B всегда возвращает ACK=2, что означает, что подтвержден только 1, и тогда A знает, что 2 не прибыл и повторно отправляет 2, но как только B получит 2, он сразу же ACK=6 отправит A, что означает, что после получения 2 также будет получено 345, и можно передать 6 напрямую, как показано на следующем рисунке:

Это просто очень простое решение. В настоящее время, после Linux 2.4, был принят более продвинутый метод. Если вы хотите узнать больше, вы можете перейтиздесь

атака

Типичным сценарием является DDOS-атака, которую также можно назвать атакой tcp SYN Flood, также известной как флуд-атака; Согласно приведенному выше анализу, мы знаем, что процесс рукопожатия tcp занимает много времени.Когда клиентская сторона инициирует запрос на соединение, серверная сторона отвечает, а затем ждет окончательной подтверждающей информации от клиента.По умолчанию Linux будет ждать от 1 до 63 с.(при наличии специальных настроек это время может достигать 1-2 мин), по умолчанию максимум 63 с до отключения, предыдущий период был в полуподключенном состоянии, сервер не будет отбрасывать эти соединений, но будет ждать, представьте, если кто-то вдруг подумает, что ваш сервер отправляет десятки миллионов запросов на соединение в одно мгновение, но игнорирует ответ сервера, что легко приведет к тому, что наше обычное соединение tcp не сможет войти, в результате чего будет отключена служба отказ В этом случае, а ему нужен только простой скрипт для отбрасывания пакетов для вас, эта ситуация приведет к тому, что сервер будет казаться недоступным для обычных клиентов. . Стоимость этого вида атаки относительно невелика, но с защитой особенно хлопотно, потому что вы должны убедиться, что нормальный не может быть отклонен из-за увеличения количества посещений.

Еще одна атака, не такая серьезная, как эта.ACK-атака флудом, Желающие могут проверить это сами.

TCP — чрезвычайно сложный протокол.Сегодня мы узнали о трехэтапных рукопожатиях, четырех взмахах рук и скользящих окнах за один захват пакета. Механизм повторной передачи тайм-аута и типичный метод атаки tcp, я надеюсь, что это поможет вам понять tcp;

Репутация: Вышеприведенный контент относится к личному пониманию и резюме.Если у вас есть какие-либо вопросы, пожалуйста, укажите~