Часть 1Введены подготовительные знания по программированию сокетов. У вас есть ощущение, что вы хотите немедленно начать понимать сетевое программирование или даже начать писать код? Не волнуйтесь, в сетевом программировании есть еще одна важная концепция. TCP/IP, китайский язык имя называется По сути, TCP/IP — это протокол и один из самых важных протоколов в сетевом программировании. В протоколе TCP/IP задействовано слишком много содержимого, но автор слишком хорошо осведомлен, чтобы представить вам весь протокол TCP/IP. предыдущая статья Что именно сделали четыре волны? Каково состояние розетки? Как меняется состояние сокета во время выполнения каждого API? Я надеюсь, что благодаря этой статье вы сможете глубже понять весь процесс изменения состояния сокета во время установления и отключения TCP-соединения.
несколько терминов
SYN: Синхронизировать порядковые номера, Синхронизировать порядковые номера, действует только в том случае, если трехстороннее рукопожатие устанавливает TCP-соединение. Представляет новый запрос TCP-подключения.
ACK: Номер подтверждения, Номер подтверждения, флаг подтверждения для запроса TCP, а также указывает, что одноранговая система успешно получила все данные.
FIN: Флаг завершения, FINISH, используется для завершения сеанса TCP, но соответствующий порт все еще открыт, готов к приему последующих данных.
Трехстороннее рукопожатие TCP
Установка соединения будет иметь следующий процесс
1) Сервер завершает установление сокетного соединения через сокет (инициализирует сокет), связывает (привязывает ip-порт), слушает (запускает службу мониторинга) и вызывает функцию принятия для подготовки к приему внешних соединений запроса Этот шаг называется пассивным открытие
2) Клиент завершает установление соединения через сокет (сокет инициализации) и вызывает функцию подключения, чтобы инициировать активное открытие. В это время клиент отправляет на сервер раздел SYN J. Функция J состоит в том, чтобы сообщить сервер, что в следующем процессе передачи данных J является начальным порядковым номером для клиента для передачи данных в соединении
3) После того, как сервер получит сегмент SYN от клиента, ему необходимо ответить на сигнал подтверждения ACK, J+1, что означает, что сервер получил запрос клиента и подтвердил начальный серийный номер клиента, и сервер отправить SYN-сегмент K для клиента. Для клиента роль K состоит в том, чтобы сообщить клиенту, что в следующем процессе передачи данных K является начальным порядковым номером данных, передаваемых сервером в соединении.
4) После того, как клиент получает сегмент SYN от сервера, он отвечает сигналом подтверждения (ACK) K+1. Соединение успешно установлено.
Весь процесс установления соединения требует как минимум трех подразделов, поэтому он называется трехсторонним рукопожатием TCP. Ниже представлена блок-схема трехэтапного рукопожатия TCP:
четырехстороннее рукопожатие TCP
TCP устанавливает соединение через трехстороннее рукопожатие, однако для отключения требуется четырехстороннее рукопожатие Процесс разъединения TCP описывается следующим образом:
1. Клиентское приложение вызывает функцию закрытия.В TCP конец, который вызывает close первым, считается активно закрытым, а конец, который активно закрыт, отправляет сегмент FIN, что означает, что данные были отправлены;
2. Другой конец (т. е. сервер) получает запрос на завершение работы, а также получает раздел FIN и начинает выполнять операцию пассивного завершения работы, которая называется окончанием пассивного завершения работы. Этот раздел FIN подтверждается TCP, и клиенту отправляется раздел ACK.Полученный FIN также передается приложению как символ конца файла, что означает, что приложение не получит данные о соединении после получения ФИН.;
3. После этого приложение, получившее конец файла, закроет свой сокет, а TCP сервера также отправит раздел FIN;
4. Клиент получает раздел FIN, подтверждает окончательную операцию закрытия и отправляет раздел ACK на сервер.
В течение всего процесса подключения каждому концу требуется раздел FIN и ACK для закрытия и подтверждения закрытия.Всему процессу обычно требуется всего 4 раздела, поэтому его также называют четырехсторонним рукопожатием TCP. Ниже приведена блок-схема четырехэтапного рукопожатия для TCP для закрытия соединения:
На самом деле передача по сети не подключена, в том числе TCP. Так называемые «подключение» и «отключение» TCP на самом деле являются просто виртуальным именем, а лишь поддерживают «соединение» с обеих сторон связи». Статус», чтобы было похоже на наличие соединения, поэтому очень важно понимать переход состояния TCP. Далее мы представим состояние сокета и изменения состояния сокета во время процесса установления и отключения соединения TCP. .
состояние сокета
Socket определяет 11 состояний: LISTEN, SYN-SENT, SYN-RECEIVED, ESTABLISHED, FIN-WAIT-1, FIN-WAIT-1, CLOSE_WAIT, FIN_WAIT, LAST-ACK, TIME-WAIT, CLOSING, CLOSED.
Предположим, что служба A запрашивает подключение к службе B.
LISTEN: Начать устанавливать соединение. В это время сокет успешно инициализирован и ожидает соединения
SYN-SENT: A успешно отправляет запрос на соединение B, ожидая ответа другой стороны.
SYN-RECEIVED: B получил запрос на соединение от A и ответил, чтобы подтвердить соединение с A. Это состояние указывает, что он ожидает, пока A также ответит, чтобы подтвердить получение этого сообщения.
УСТАНОВЛЕНО: Указывает, что соединение было успешно установлено; это состояние является нормальным состоянием передачи данных на этапе соединения.
FIN-WAIT-1: ожидание подтверждения активного запроса на отключение или отключение при отклонении параллельного запроса, это состояние обычно длится короткое время и его трудно зафиксировать.
FIN-WAIT-2: Ожидание отключения B, это состояние обычно длится короткое время, но если B блокирует или не закрывает соединение по другим причинам, это состояние будет длиться долго.
CLOSE-WAIT: B получил запрос на отключение от A и ожидает, пока локальное приложение отправит запрос на отключение.
ЗАКРЫТИЕ: A ожидает сигнала подтверждения закрытия соединения от B. Когда A получает запрос на отключение от локальной программы, он отправляет запрос на отключение B и входит в это состояние
LAST-ACK: B ожидает сигнала подтверждения для отключения
TIME-WAIT: подождите некоторое время, чтобы подтвердить, что B получает сигнал подтверждения закрытия соединения от A.
ЗАКРЫТО: соединение полностью закрыто
Итак, как изменяется состояние TCP в процессе завершения TCP-подключения?
Давайте взглянем на следующую картинку, которая представляет собой классическую блок-схему изменений состояния TCP в сетевом программировании UNIX:
На стороне сервера вызовите функцию сокета для создания сокета, функция возвращает дескриптор файла сокета, вызовите функцию привязки для привязки IP-адреса и порта, а затем вызовите функцию прослушивания, сокет становится прослушивающим сокетом, входит в Состояние LISTEN, и вызовы accept to wait Request (для проверки состояния LISTEN можно создать socket=>bind=>listen, а затем выйти через 10 секунд сна, это можно увидеть командой netstat сразу после запуска сервера)
Клиент вызывает соединение, активно открывает дескриптор файла и запрашивает установление соединения.В это время он инициирует трехэтапное рукопожатие TCP и переходит в состояние SYN-SENT.
В это время сервер вызывает accept и находится в стадии блокировки, после получения запроса на подключение от клиента он переходит в состояние SYN-RECEIVED, отвечает клиенту подтверждающим сообщением и ожидает подтверждения подключения клиентом.
После того, как клиент получает сообщение подтверждения соединения SYN от сервера, TCP завершает трехэтапное рукопожатие, функция соединения возвращается, подтверждает установление соединения, переходит в состояние ESTABLISHED и отправляет подтверждающее сообщение ACK на сервер. (Когда второе рукопожатие завершено и второй сегмент рукопожатия получен клиентом, функция соединения возвращается.)
На стороне сервера, после получения подтверждающего сообщения от клиента, также возвращается accept, и сервер также переходит в состояние ESTALISHED. (Когда сервер получает третий подраздел шага рукопожатия, возвращается функция accept, то есть возвращается половина времени RTT после соединения.)
После того, как клиент и сервер успешно установили "соединение", они начинают общение. В это время будет вызвана функция чтения/записи для чтения и записи данных. После чтения и записи данных они готовы закрыть соединение.
Предположим, что клиентское приложение получает ответное сообщение от сервера, завершает процесс связи, готовится закрыть приложение и вызывает функцию закрытия, чтобы инициировать активное завершение работы.В это время клиент входит в состояние FIN-WAIT1, отправляет сообщение FIN на сервер и ждет подтверждения от сервера.
Сервер получает подсекцию FIN(M) запроса на отключение, в это время функция чтения возвращает 0. Сервер готов выполнить операцию закрытия, больше не получает никаких данных и отправляет подтверждающее сообщение ACK (M+1) на клиент.
После того, как клиент получит раздел подтверждения, это означает, что сервер получил запрос на отключение, в это время он не будет отправлять данные и будет ждать, пока сервер отключится и войдет в состояние FIN-WAIT2.
После того, как сервер отправляет подтверждение на отключение, он вызывает функцию close для разрыва соединения, после успешного завершения функции close отправляет секцию FIN клиенту, переходит в состояние LASK-ACK и ожидает подтверждения от клиента.
После того, как клиент получает от сервера сегмент FIN(N) с отключенным соединением, он отправляет на сервер подтверждающий сегмент ACK и переходит в состояние TIME-WAIT, в это время он будет ждать достаточно времени, что составляет примерно 2 самого длинного сегмента. life.times (2MSL), подтверждая, что сервер получил раздел подтверждения об отключении, а затем исчезает. После того, как сервер получает сегмент подтверждения ACK (N+1) об отключении от клиента, он указывает, что соединение было полностью отключено, и в это время переходит в состояние CLOSED.
Прочитав большой абзац текста выше, он может показаться немного скучным или даже немного запутанным, давайте посмотрим на эту анимацию:
Суммировать
На этот раз я в основном расскажу о состоянии TCP и об изменениях состояния TCP в процессе установления и отключения TCP-соединения. Освоение этого будет очень полезно для понимания состояния каждого процесса в сетевом программировании, например, проверки того, служба запущена. , вы можете пройтиnetstat -nlp | grep '端口号'
и проверьте строку описания состояния службы. Если она находится в состоянии LISTEN, это означает, что служба была запущена нормально. Если служба находится в других состояниях, вы можете использовать состояние службы для дальнейшего устранения проблемы.
Оригинал статьи, ограниченный стиль написания, недостаток знаний и знаний, если есть неточности в статье, сообщите пожалуйста.
Если эта статья была вам полезна, ставьте лайк, спасибо ^_^
Для более интересного контента, пожалуйста, обратите внимание на личный публичный номер.