No handshake de 4 vias, temos o seguinte:
FIN ------->
<------- ACK
<---x--- FIN (what if this packet is lost?)
ACK ------->
O que acontece se o terceiro pacote for perdido, ele será retransmitido? Observe que no momento em que o terceiro pacote for enviado, o programa provavelmente terá destruído o soquete e, portanto, não poderá mais enviar nada!
Responder1
A resposta curta é que nenhum pacote tem garantia de chegada. Qualquer número de condições pode fazer com que os pacotes sejam descartados ou perdidos em trânsito. O TCP inclui regras de repetição para garantir que os dados cheguem.
Seu cenário é uma conexão semifechada. Um lado fecha a conexão e só pode ler os dados até que o outro lado feche a conexão.
FIN ------>
<------ ACK
O lado que envia o pacote FIN percorrerá os estados FIN_WAIT1, FIN_WAIT2 e TIME_WAIT conforme a conexão é fechada. O lado que recebe o pacote FIN entrará em CLOSE_WAIT. Ao fechar a conexão, ele tentará novamente os pacotes FIN de acordo com suas regras de nova tentativa até receber um ACK ou expirar. Até que o segundo FIN seja enviado, a conexão estará em estado semifechado.
<------ FIN
ACK ------>
As conexões podem ser fechadas com 3 pacotes. Eles são comuns nos dumps de protocolo que vejo. Em alguns casos, a resposta ao primeiro FIN será um RST (reset), e o ACK final será substituído por um RST.
FIN ------>
<------ FIN,ACK
ACK ------>
Em alguns casos, um RST (reset) é enviado no lugar do ACK e o ACK final é substituído por um RST.
FIN ------>
<------ RST
RST ------>
Devido ao atraso da rede, é possível que ambas as extremidades fechem uma conexão ativa. Neste caso, o ACK, os pacotes podem ser entregues em qualquer ordem.
<------ FIN
FIN ------>
<------ ACK
ACK ------>
Responder2
DeRFC 793:
Conexões semiabertas e outras anomalias
Uma conexão estabelecida é considerada "semiaberta" se um dos TCPs fechou ou abortou a conexão em seu final sem o conhecimento do outro, ou se as duas extremidades da conexão ficaram dessincronizadas devido a uma falha que resultou na perda de memória. Essas conexões serão redefinidas automaticamente se for feita uma tentativa de enviar dados em qualquer direção. No entanto, espera-se que conexões semiabertas sejam incomuns e o procedimento de recuperação seja levemente complicado.