Home

Page 50
Page 50
background image

квитирования,  мы,  по  сути,  лишь  рассмотрели  базовый  инструмент,  впереди  у  нас  рассмотрение 
того, как этим инструментом пользоваться. Мы в общих чертах рассмотрели принципы установки 
TCP  соединения  и  принципы  использования  полей Sequence Number и Acknowledged Number для 
квитирования данных. Теперь столь же кратко рассмотрим принципы разрыва TCP соединения.  

Важно  понимать,  что  когда TCP соединение  установлено,  ОБЕ  стороны-участники 

соединения  абсолютно  симметричны,  в  отличие  от  процесса  установки  соединения,  когда  явно 
выражена асимметрия – клиент и сервер ведут себя по-разному в процессе установки соединения. 
Если устанавливает соединение всегда клиент (или, по крайней мере, клиентом называют того, кто 
устанавливает соединение), то разрыв соединения может инициировать любой из его участников – 
они  симметричны.  Положим,  что  один  из  участников  соединения,  назовем  его  узел A, больше  не 
собирается  передавать  данные  в  соединении  для  узла B. Значит  ли  это,  что  и  узел  В  больше  не 
собирается  передавать  данные  узлу  А?  Формально  говоря,  нет.  Крайне  важно  понять – TCP 
соединение, по сути, состоит из двух условных полусоединений, в каждом из которых одна сторона 
может  передавать  другой  данные  с  квитированием,  разрыв TCP соединения – это  независимый 
отказ  КАЖДОЙ  стороны  от  дальнейшей  работы  в  рамках  данного  соединения.  И  если  один  из 
участников TCP соединения  (узел A) хочет  разорвать  соединение,  он  должен  уведомить  своего 
партнера (узел B) об этом, узел B подтверждает узлу А, что принял его отказ от передачи данных в 
соединении, но соединение при этом НЕ закрывается, а находится в так называемом полузакрытом 
состоянии:  узел  А  в  таком  случае  не  имеет  права  передавать  данные  узлу  В,  но  при  этом  узел  В 
имеет  право  передавать  данные  узлу  А  и  узел  А  обязан  их  квитировать.  И  только  в  том  случае, 
когда и узел В сообщит узлу А о своем намерении разорвать TCP соединение, а узел А подтвердит 
узлу  В,  что  принял  от  него  предложение  разорвать  соединение, TCP соединение  можно  считать 
разорванным.  Рассмотрим,  как  это  происходит.  Если  узел  А  желает  закрыть  свою  половинку 
соединения, он должен отправить узлу В TCP сегмент, в котором устанавливаются влаги FIN, ACK, 
использование  флага FIN и  есть  явное  предложение  о  разрыве  своего  полусоединения.  При  этом 
поле Sequence Number в этом сегменте должно принимать текущее значение для того, чтобы узел В 
мог убедиться в том, что все данные, которые узел А послал до момента разрыва полусоединения 
получены узлом В, поле Acknowledged Number такого сегмента так же должно принимать текущее 
положенное значение – ведь передача данных в обратном направлении, от В к А еще не закончена и 
поэтому узел А должен верно квитировать все получаемые данные и как следствие верно указать 
номер  ожидаемого  байта  в  сегменте  с  флагом FIN (поэтому  и  флаг ACK в  этом  сегменте  тоже 
устанавливается). Пусть узел В получил такой сегмент от узла А. Рассматриваем, как узел В должен 
ответить на этот сегмент. Очевидно, целью такого ответа является подтверждение узлом В того, что 
он  понял  намерение узла  А  разорвать  свое  полусоединение.  Такой  сегмент НЕ  должен  содержать 
флага FIN – это бы означало, что узел В хочет разорвать свою половину соединения, мы же пока 
обсуждаем,  как  узел  В  должен  дать  понять  узлу  А,  что  понял  его  намерение  разорвать  свою 
половину соединения. Ясно, что в поле Sequence Number такого сегмента должно быть установлено 
текущее  значение – узлу  В  еще  предстоит  передавать  данные  узлу  А  (если  узел  В  пожелает), 
главный  вопрос – что  указать  в  поле Acknowledged Number? Так  как  сегмент  с  флагом FIN не 
содержит  полезных  данных,  то  логично  в  соответствии  с  вышесказанным  установить  в  поле 
Acknowledged Number то же значение, которое узел В использовал в этом поле ранее, т.е. значение, 
указанное  в  поле Sequence Number сегмента  с  флагом FIN, посланного  узлом  А  (и,  ясное  дело, 
необходимо  установить  флаг ACK). Однако  такое  «подтверждение»  того,  что  узел  В  понял 
намерение  узла  А  разорвать  свое  полусоединение  неприемлемо!  Действительно,  в  ряде  случаев 
(когда  предыдущий  сегмент,  посланный  узлом  В  не  содержал  полезных  данных,  а  был  лишь 
квитанцией)  такой  сегмент  НЕ  будет  отличаться  от  предыдущего  посланного  узлом  В  сегмента, 
станция  А  приняв  такой  сегмент  НЕ  может  сделать  из  него  однозначного  вывода,  что  узел  В 
правильно  понял  ее  намерение  разорвать  соединение!  Узлу  В  в  сегменте-ответе  на  полученный 
сегмент  с  флагом FIN необходимо  дать  понять  узлу  А,  что  его  уведомление  о  разрыве 
полусоединения принято. В TCP это делается следующим образом: когда узел В получает сегмент с 
флагом FIN от узла А, он формирует сегмент в ответ, в котором записывает в поле Acknowledged 
Number число, на единицу большее, нежели там должно быть записано (т.е. узел В квитирует некий 
лишний  байт),  а  так  как  узел  А  знает,  байты  с  какими  номерами  он  передавал  узлу  В,  то 
квитирование  такого  «несуществующего»  байта  будет  однозначно  воспринято  узлом  А  как 
подтверждение  получения  узлом  В  сегмента  с  флагом FIN. Фактически,  квитирование  сегмента  с 
флагом FIN аналогично  ответу  на  сегмент  с  флагом SYN – и  в  том  и  в  другом  случае 
подтверждение получения сегмента с таким флагом делается путем передачи в поле Acknowledged 


Copyright © 2021 Файлообменник files.d-lan.dp.ua

Использование любых материалов сайта возможно только с разрешения автора.