Przejdź do treści

Podstawy protokołu TCP

Transmission Control Protocol (TCP) - protokół używany na codzień przez każdego z nas. W tym artykule przyjrzę się jak działa, jaka jest struktura nagłówka, mechanizmy działania i sposób, w jaki zapewnia niezawodność komunikacji.

Czym jest?

TCP to protokół warstwy transportowej modelu OSI, używany do przesyłania danych między aplikacjami. Najważniejszą cechą TCP jest połączeniowość i niezawodność - dane trafiają do odbiorcy w odpowiedniej kolejności, bez duplikatów i z kontrolą błędów.

TCP pracuje ponad protokołem IP i razem tworzą znane połączenie TCP/IP.

Proces ustanawiania połączenia - 3-way handshake

Każda komunikacja TCP zaczyna się od ustanowienia połączenia w trzech krokach:

  1. SYN - klient wysyła pakiet inicjalizujący z ustawioną flagą SYN
  2. SYN-ACK - serwer odpowiada pakietem potwierdzającym z flagami SYN i ACK
  3. ACK - klient potwierdza otrzymanie i połączenie zostaje ustanowione
sequenceDiagram
    participant Klient
    participant Serwer

    Klient->>Serwer: SYN
    Serwer->>Klient: SYN + ACK
    Klient->>Serwer: ACK
    Note over Klient,Serwer: Połączenie ustanowione

Ten mechanizm zapobiega przypadkowym połączeniom i pomaga zsynchronizować numery sekwencyjne.

Struktura nagłówka TCP

Pole Rozmiar (bitów) Opis
Port źródłowy 16 Numer portu wysyłającego
Port docelowy 16 Numer portu odbiorcy
Numer sekwencyjny 32 Pozycja pierwszego bajtu w strumieniu
Numer potwierdzający 32 Oczekiwany numer sekwencyjny od drugiej strony
Offset danych 4 Długość nagłówka TCP
Flagi 9 SYN, ACK, FIN, RST, PSH, URG itd.
Okno odbiorcze 16 Ile bajtów można wysłać zanim trzeba potwierdzić
Suma kontrolna 16 Sprawdzenie błędów w nagłówku i danych
Wskaźnik pilności 16 Używany z flagą URG
Opcje (opcjonalne) zmienna Np. MSS, ustawienie wielkości okna (window scaling)

Flagi używane w komunikacji TCP

  • SYN - rozpoczęcie połączenia
  • ACK - potwierdzenie danych
  • FIN - zakończenie połączenia
  • RST - natychmiastowe przerwanie połączenia
  • PSH - dane powinny być przekazane aplikacji natychmiast
  • URG - oznaczenie danych jako pilnych

Gwarancje i mechanizmy TCP

Kolejkowanie i kontrola sekwencji

TCP numeruje każdy pakiet danych wysyłany w strumieniu. Dzięki temu odbiorca może ułożyć je w odpowiedniej kolejności, nawet jeśli pakiety dotarły w różnej kolejności.

Potwierdzenia i retransmisje

Brak potwierdzenia (ACK) w określonym czasie skutkuje retransmisją. To mechanizm niezawodności, który minimalizuje utratę danych.

sequenceDiagram
    participant Klient
    participant Serwer

    Klient->>Serwer: FIN
    Serwer->>Klient: ACK
    Note over Klient,Serwer: Połączenie częściowo zamknięte (half-close)

    Serwer->>Klient: FIN
    Klient->>Serwer: ACK
    Note over Klient,Serwer: Połączenie zamknięte po obu stronach

Kontrola przeciążenia

TCP dynamicznie reguluje szybkość przesyłania danych na podstawie sygnałów z sieci:

  • Slow start - na początku połączenia TCP powoli zwiększa liczbę bajtów w locie.
  • Congestion avoidance - dostosowuje okno transmisji przy przeciążeniu.
  • Fast retransmit - przy wykryciu utraty pakietu retransmituje go bez czekania na timeout.

Zamykanie połączenia

Zamknięcie TCP również odbywa się w krokach:

  1. Jedna strona wysyła FIN
  2. Druga strona odpowiada ACK
  3. Druga strona wysyła FIN
  4. Pierwsza strona odpowiada ACK

W niektórych przypadkach zamknięcie może być jednostronne (tzw. half-close).

TCP vs UDP

Cecha TCP UDP
Połączeniowy Tak Nie
Kolejność danych Gwarantowana Brak gwarancji
Retransmisja Tak Nie
Zastosowania HTTP, SSH, FTP DNS, VoIP, streaming

Jak to działa w Linuxie?

Już wiemy jak to działa, ale jak to wygląda w praktyce na systemie Linux?

  • kernel implementuje całą logikę protokołu TCP - od ustanawiania połączeń (SYN, ACK, FIN), przez retransmisje, kontrolę przeciążenia, aż po zamykanie połączeń.

  • procesy użytkownika (np. curl, ssh, nginx) korzystają z interfejsu socketów, który pozwala im wysyłać i odbierać dane przez TCP, ale nie zajmują się one samym protokołem - to robi jądro naszego systemu operacyjnego

Przykład działania:

  1. aplikacja wywołuje funkcję connect() na sockecie TCP
  2. kernel inicjuje 3-way handshake
  3. kernel buforuje dane, zarządza oknami TCP i pilnuje retransmisji
  4. aplikacja odbiera dane przez read() lub recv() - nie widzi mechaniki TCP, tylko czysty strumień bajtów
  5. po zakończeniu komunikacji aplikacja wywołuje close() na sockecie, co inicjuje proces zamykania połączenia

Gdzie to jest?

Implementacja TCP znajduje się w kodzie jądra Linuksa - konkretnie w podsystemie sieciowym (net/ipv4/tcp.c, tcp_input.c, tcp_output.c itd.)

Możesz to podejrzeć w źródłach Linuksa, kod jest dostepny również online, ale co Ci szkodzi pobrać i przejrzeć samemu?

git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
cd linux/net/ipv4/

Podsumowanie

TCP to solidny, dobrze zaprojektowany protokół, zrozumienie jego działania pomaga nie tylko przy debugowaniu połączeń, ale też przy projektowaniu usług, które mają być skalowalne i odporne na błędy sieciowe.