Curso de Redes – Protocolo TCP – Finalizando uma conexão entre dois hosts

Protocolo TCP – Finalizando uma conexão entre dois hosts

Na lição anterior mostramos como é estabelecida uma conexão TCP entre dois hosts em uma rede, pelo processo denominado de Handshake de Três Vias. Após o estabelecimento dessa conexão, os hosts podem trocar dados entre si livremente.

Quando a troca de dados chega ao fim – por exemplo, quando um download é finalizado ou quando você sai de um website – a conexão entre os hosts deve ser finalizada. Para isso, é realizado um processo de finalização da conexão,  parecido com o processo de estabelecimento de conexão. Porém, há algumas diferenças.

Por exemplo, como as conexões realizadas via protocolo TCP são full-duplex (dados podem trafegar em ambas as direções independentemente da outra direção), cada host deve finalizar a conexão independentemente. Ou seja, cada host deve enviar um segmento com a flag FIN ativada quando terminar de enviar seus dados. Assim quando o protocolo TCP em um host recebe um segmento com a flag FIN, ele informará à aplicação envolvida na comunicação de que o outro host encerrou a transmissão de dados.

Chamamos o processo de finalização da conexão TCP de “Handshake de Quatro Vias”, pois são trocados ao todo quatro segmentos entre os hosts, ao contrário do processo de estabelecimento de conexão, onde são trocados três segmentos.

O host que emite primeiramente o segmento FIN realiza o que chamamos de finalização ativa, e o host que recebe esse segmento realiza uma finalização passiva. A seguir listamos as etapas da finalização de uma conexão TCP:

  1. Um dos hosts (vamos chamá-lo de host A) termina de enviar seus dados e então envia um segmento TCP com a flag FIN (finalization) ativada para o outro host, e aguarda o retorno. Neste ponto, o host A ainda pode receber dados do outro host, porém não aceita mais dados da aplicação local para envio.
  2. O outro host (host B) recebe o segmento e então responde com outro segmento confirmando (ACK) o número de sequência recebido + 1. Um segmento FIN utiliza um número de sequência, assim como um segmento SYN.
  3. O host B então emite uma mensagem para a aplicação envolvida na comunicação informando que a transmissão de dados finalizou, e envia um segmento TCP com a flag FIN ativa, fechando sua conexão.
  4. O host A, após receber o segmento FIN do host B, responde de volta confirmando (ACK) o número de sequência recebido + 1 (incrementado). Neste ponto, a conexão está encerrada entre os dois hosts.

As conexões entre hosts são geralmente iniciadas por um host cliente, e podem ser finalizadas tanto pelo cliente quanto pelo servidor (ou outro host). Porém, é mais comum que o próprio cliente que iniciou a conexão a finalize, pois os processos na máquina cliente são normalmente controlados por um usuário, que em algum momento encerra a aplicação que estava transmitindo e recebendo dados pela rede – por exemplo, o cliente fecha o navegador e encerra as conexões que estavam ativas com os websites abertos.

A figura a seguir detalha o esquema de troca de segmentos entre os dois hosts ao finalizar a conexão TCP.

Handshake de quatro vias - finalizando conexão TCP

A figura anterior mostra também os estados dos dispositivos durante o processo de finalização da conexão. Inicialmente, ambos os hosts (cliente e servidor) esão no estado “ESTABLISHED“, que significa que a conexão está estabelecida e que podem trocar dados. Os demais estados são explicados a seguir:

  • FIN_WAIT_1: Após enviar o segmento FIN ao servidor, o cliente (que solicitou a finalização da conexão) entra no estado FIN_WAIT_1, no qual aguarda tanto o ACK, quanto o segmento FIN do servidor. O cliente ainda pode receber dados, mas não pode mais enviar dados nesta conexão.
  • CLOSE_WAIT: O servidor está aguardando que o processo da aplicação local sinalize que está pronta para finalizar. Após o encerramento da aplicação local, o segmento FIN é enviado ao cliente.
  • FIN_WAIT_2: Após aguardar o recebimento do segmento FIN do servidor, o cliente recebe esse segmento e envia de volta um segmento ACK.
  • LAST_ACK: O servidor está aguardando um ACK (confirmação) do segmento FIN que ele enviou anteriormente. Ao receber essa confirmação, fecha a conexão de seu lado.
  • TIME_WAIT: O cliente então aguarda por um período de tempo igual a duas vezes o MSL (maximum segment lifetime), para ter certeza de que o ACK enviado foi recebido pelo servidor. Decorrido esse tempo, o timer expira e a conexão estará fechada (CLOSED).

MSL: Maximum Segment Lifetime (Tempo de Vida Máximo do Segmento), é o tempo durante o qual um segmento TCP pode existir em uma rede antes de ser descartado. É utilizado para calcular o valor do estado TIME_WAIT, que é de 2 vezes o valor do MSL.Podemos determinar o valor do MSL em um sistema Linux (usei a distribuição Debian como exemplo) executando o comando a seguir no terminal:

# sysctl net.ipv4.tcp_fin_timeout

Veja a saída abaixo:

Maximum Segment Lifetime no GNU Debian Linux

O MSL desse sistema é, portanto, de 60 segundos. O RFC 793 determina que o MSL deve ser de 2 minutos, mas as implementações comuns do protocolo TCP utilizam também temporizações de 30 ou 60 segundos, por exemplo.

Também é possível executar o processo de finalização de uma conexão TCP usando um handshake de três vias. Neste caso, o host A envia o segmento FIN, e o host B responde com um único segmento combinando os passos 2 e 3 descritos anteriormente, ou seja, com as flags FIN e ACK juntas, e então o host A responde de volta com o ACK. Este é um método muito comum de finalização da conexão, e a figura a seguir mostra uma captura de pacotes do Wireshark onde podemos visualizar esse processo:

Finalizando uma conexão TCP

Na figura podemos ver que meu host, de IP 192,168,1,100, está finalizando a conexão ao servidor remoto de IP 64.233.186.121. Meu host envia o segmento FIN, recebendo de volta um segmento FIN + ACK, e então finaliza o processo confirmando a recepção desse segmento com outro ACK.

Uma observação importante é a de que uma conexão pode estar em um estado chamado “half-open” (semi-aberta), na qual um dos hosts executou o processo de finalização da conexão, mas o outro não. Assim, o host que finalizou não pode mais enviar dados por esta conexão, mas o outro host ainda pode, de modo que o host que iniciou a finalização da conexão continua a receber dados até que o outro host também finalize a conexão.

Anterior: Estabelecendo uma conexão TCP entre dois hosts

 

Sobre Fábio dos Reis (1273 Artigos)
Fábio dos Reis trabalha com tecnologias variadas há mais de 25 anos, tendo atuado nos campos de Eletrônica, Telecomunicações, Programação de Computadores e Redes de Dados. É um entusiasta de Unix, Linux e Open Source em geral, adora Eletrônica e Música, e estuda idiomas, além de ministrar cursos e palestras sobre diversas tecnologias em São Paulo e outras cidades do Brasil.
Contato: Website

2 Comentários em Curso de Redes – Protocolo TCP – Finalizando uma conexão entre dois hosts

  1. Adriano Sales // 02/11/2015 em 14:10 // Responder

    Excelente explicação, mais uma vez obrigado por compartilhar!

  2. Ângela Santos // 23/08/2016 em 11:09 // Responder

    Bom dia a Boson,venho me informar sobre usuarios na rede,onde se instalou uma torre esta na rede e via Ethernet,porem a impressora não imprime se visualiza ao sistema mas ha resposta de impressão.Windows Server 2008R2.
    Desde já agradeço e aguardo retorno.

Escreva um comentário

Seu e-mail não será divulgado


*