.3. TCP
Visao Geral
- Processo a processo.
- entrega fluxo de bytes de forma ordenada e confiável
- dutado (pipelined)
- buffers de envio e recepção, e statefull.
- O trafego eh Full Duplex (bi-direcional na mesma conexão)
- orientado a conexão
- Handshaking de 3 vias e verifica estados do emissor/receptor antes de trocar dados.
- fluxo controlado: receptor nao eh afogado.
- cliente: inicia conexão -> active open
- servidor -> passive open
Estrutura do Header
- No. Porta orig/dest (16 bits cada)
- Nro de Sequencia (32 bits) -> receptor indica no ack o próximo nro de seq.
- Nro de Confirmacao (32 bits)
- tamanho do header (5 bits usualmente)
- bits unicos
- U(rgent)
- A(ck)
- P(ush) -> nao bufferiza pacote
- R(eset), S(ync) e F(inal) -> focados em conexão
- janela receptor (16 bits) -> controle de fluxo e congestionamento
- checksum (16 bits)
- ptr dados urgentes (16 bits)
MSS (Maximum Segment Size) e numeração de segmentos
Representa o tamanho de maior bloco de dados que o TCP permite enviar num unico segmento (definido pelo maximo transporte da camada de enlace).
- ajustado automaticamente pelo SO (default = 536 bytes)
- ethernet padrão (default 1460 bytes)
Numero de segmentos
[!example] aplicação quer enviar 500 mill bytes.
Numa camada de transporte TCP com MSS = 1000 bytes, a transmissão TCP: 500 partes de 1000 bytes. Neste caso, serão enviados 500 segmentos/pacotes. Nro. de sequencia cresce de acordo com o segmento (nesse caso, Nro += 1000).
Handshake de 3 vias
Solicitação de conexão:
- cliente: primeiro pacote. Syn = 1, Ack = 0, Nro de sequencia aleatório
- servidor: syn = 1, ack = 1, numero do ack = n. de seq do cliente + 1, Nro. seq = aleatório
- cliente: sync = 0, ack = 1, confirma n de sequencias no ack (n. seq anterior + 1), nro de sequencia = correto, dados
Numeros de ACKs
ACK = nro de transmissao do cliente + (existem dados) ? bytes : 1
Retransmissão
Os ACK’s são cumulativos. Quando um chega, ele sempre confirma os anteriores, pois aquele ACK nunca teria sido enviado sem a confirmação dos anteriores.
- no TCP, ha um único timer de transmissão, referente ao segmento mais antigo sem ACK.
retransmissões são disparadas por:
- eventos de timeout.
- ACK’s duplicados.
O timer de confirmação eh sempre baseado no mais antigo que espera ACK
Retransmissão rápida
Se o emissor receber 3 ACKs duplicados, ou seja, 4 idênticos, para o mesmo segmento, ele retransmite o pacote antes mesmo de seu timeout.
Isso acontece quando um pacote $i$ eh perdido e os pacotes $i+1, i+2 \ e \ i+3$ chegam corretamente.
Encerramento de Conexão
Half Close -> já que conexões são full-duplex, cada lado deve finalizar de forma independente. O transmissor envia um pacote FIN. A camada de transporte do receptor avisa a aplicação de que houve tentativa de fechamento de conexão, se a aplicação quiser, devolve o pacote FIN.
Quando se recebe um FIN, cria-se um temporizador chamado de fin wait.
Timers
RTO (RTT e timeout)
- timer adaptativo
- faz uma media ponderada do round trip time e da mais peso para as medidas tiradas mais recentemente.
[!question] como definir o timeout?
deve ser maior do que o RTT, nao pode ser muito curto (retransmissoes desnecessarias) nem longo (demora para reagir a perdas)
Existem 3 variáveis:
- Sample RTT ou R -> medido desde o momento da transmissão ate receber o ACK.
- Estimated RTT ou SRTT -> média ponderada das samples recentes.
- Dev RTT ou RTTVAR (Desvio do rtt ou rtt variável)
Processo iterativo
timeout (RTO) é setado como 1s;
Quando a primeira medição R do RTT é feita, o host DEVE DEFINIR.
- RTO = 1;
- SRTT = R;
- RTTVAR = $\frac{R}{2}$;
- RTO = $SRTT + K\times RTTVAR$; com $K = 4$ (definido empiricamente)
Quando a medição de $R’$ é feita: (toda vez que chega um ACK)
- RTTVAR = $(1- \beta) \times RTTVAR + \beta \times |SRTT - R’|$
- SRTT = $(1-\alpha) \times SRTT + \alpha \times R'$
o algoritmo deveria ser calculado usando $\alpha = 0.125$ e $\beta = 0.25$
Após o Cálculo, um host deve atualizar
- RTO = $SRTT + K\times RTTVAR$
- pode ter granularidade de relógio:
- RTO = $SRTT + max(G, \ K\times RTTVAR)$
Timer de Persistência
É usado para evitar impasse. Receptor envia pacote de tamanho de janela 0, pedindo para emissor aguardar.
De vez em quando, o emissor verifica o receptor com um pacote vazio perguntando se pode transmitir pacotes ou não.
Timer Keep Alive
Serve para verificar conexões inativas. Um lado verifica se o outro ainda está “Vivo”.
Time Wait
Tempo de espera quando o F(in) chega. É ajustado para 2x o tempo de vida máximo do pacote.
Controle de Fluxo
Para que o emissor não esgote o buffer do receptor, serão necessários alguns ajustes.
- RcvBuffer = tamanho do Buffer de recepção.
- RcvWindow = informa ao emissor quantidade de espaço vazio no buffer do receptor.
Receptor avisa o transmissor o quanto pode receber de dados para não ser congestionado (funciona bilateralmente, ou seja, os 2 podem fazer isso).
![[Pasted image 20250423101956.png]]
Controle de Congestionamento
Emissor envia mais dados do que a rede suporta. Retransmissão de pacotes trata o sintoma do congestionamento da rede (perda de segmentos), mas isso não trata a causa do congestionamento, que é enviar muitos pacotes na rede.
Como o congestionamento se manifesta:
- perda (drop) de pacotes
- retransmissão de pacotes.
- longos atrasos.
solução é reduzir a taxa de transmissão de dados. TCP tenta alcançar isso dinamicamente sobre o tamanho da janela.
O algoritmo do TCP tenta achar uma largura de banda ótima, para isso:
- ele aumenta a taxa de transmissão progressivamente, até ocorrer uma perda.
- aumenta a banda toda vez que chegar um ACK e diminui toda vez que ocorre perda. ![[Pasted image 20250423102734.png]]
O TCP trata 2 congestionamentos, do receptor e da rede. Para isso: • Janela fornecida pelo receptor. RcvWin -> recebido no campo do segmento TCP.
• Janela de congestionamento:
CongWin -> dinâmica.
Cada variável dessas representa o n° de bytes que o emissor pode enviar, ou seja: $LastByteSent - LastByteAcked \leq min(CongWin, RcvWin)$
Funcionamento/Resumo
- Sondagem: transmitir o mais rapido possivel ate haver perda.
- Aumenta-se congwin até ocorrer perda de pacotes.
- Se houver, diminui-se congwin
- Sondagem de novo.
- Partida lenta
- transmissor ajusta o congwin como 1 MSS (Maximum Segment Size)
- quando chega um ack, o transmissor dobra o congwin (2 MSS)
- e faz isso de novo, até havar perda de pacote.
Congwin = 1 Threshold = 64KB for (cada segmento c/ ACK): Congwin++ until (evento de perda OR: CongWin > threshold)- se não há um evento de perda, existe uma variável que limita o crescimento exponencial, chamado de
threshold. A partir do threshold, o crescimento passa a ser linear.
- Prevenção de Congestionamento
- quando há um timeout, o threshold é atribuido como metade da janela de congestionamento e a janela volta a ser 1 MSS.
![[Pasted image 20250423104541.png]]

