Osnove pouzdanog prijenosa podataka

Osnove pouzdanog prijenosa podataka

Onima koji traži Posvećen razumijevanju mreža i protokola.

Ukratko

Članak govori o osnovama pouzdanog prijenosa podataka, implementira primjere na Go, uključujući UDP i TCP. Na osnovu puta, два, tri i knjige "Kompjuterske mreže. Top-Down pristup", inače svi raspravljaju samo o Tannenbaumu i Oliferovu.

Protokol transportnog sloja

Pruža logičku vezu između procesa aplikacije koji se pokreću na različitim hostovima. Iz perspektive aplikacije, logička veza izgleda kao kanal koji direktno povezuje procese.

Osnove pouzdanog prijenosa podataka

Protokoli transportnog sloja podržavaju krajnji sistemi, ali ne i mrežni ruteri (osim - DPI). Na strani pošiljaoca, transportni sloj konvertuje podatke sloja aplikacije koje prima od procesa aplikacije slanja u pakete transportnog sloja koji se nazivaju segmenti.

Osnove pouzdanog prijenosa podataka

Ovo se radi cijepanjem (ako je potrebno) poruka sloja aplikacije na fragmente i dodavanjem zaglavlja transportnog sloja svakom od njih.

Osnove pouzdanog prijenosa podataka

Transportni sloj zatim prosljeđuje segment na mrežni sloj pošiljatelja, gdje se segment inkapsulira u paket mrežnog sloja (datagram) i šalje. Na kraju prijema, mrežni sloj izdvaja segment transportnog sloja iz datagrama i prosljeđuje ga transportnom sloju. Zatim, transportni sloj obrađuje primljeni segment tako da njegovi podaci postaju dostupni aplikaciji koja prima.

Osnove pouzdanog prijenosa podataka

Principi pouzdanog prenosa podataka

Pouzdan prenos podataka preko potpuno bezbednog kanala

Najjednostavniji slučaj. Strana koja šalje podatke jednostavno prima podatke od gornjeg sloja, kreira paket koji ih sadrži i šalje ga kanalu.

Server

package main

import (
    "log"
    "net"
)

func main() {
    // IP-адрес сервера и порт
    serverAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:12000")
    if err != nil {
        log.Fatal(err)
    }

    // создаем сокет с портом
    serverConn, err := net.ListenUDP("udp", serverAddr)
    if err != nil {
        log.Fatal(err)
    }
    // отложенное закрытие соединения
    defer serverConn.Close()

    // создаем буфер для данных
    buf := make([]byte, 1024)

    // ждем соединение
    for {
        // читаем запрос
        n, addr, err := serverConn.ReadFromUDP(buf)
        // передаем данные в ВЕРХНИЙ уровень: в нашем случае stdout
        println(string(buf[0:n]), " form ", addr.IP.String())
        if err != nil {
            log.Fatal(err)
        }
        // ответа нет, т.к. это UDP + надежный канал
    }
}

Kupac

package main

import (
    "fmt"
    "log"
    "net"
    "time"
)

func main() {
    // IP-адрес сервера и порт
    serverAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:12000")
    if err != nil {
        log.Fatal(err)
    }
    // локальный IP-адрес и порт
    localAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0")
    if err != nil {
        log.Fatal(err)
    }
    // установка соединения
    conn, err := net.DialUDP("udp", localAddr, serverAddr)
    if err != nil {
        log.Fatal(err)
    }
    // отложенное закрытие соединения
    defer conn.Close()

    for {
        // получение данных от ВЕРХНЕГО уровня
        fmt.Print("Введите строчное предложение > ")
        var msg string
        _, err := fmt.Scanf("%s", &msg)
        if err != nil {
            log.Fatal(err)
        }
        // передается поток байт, а не строка
        buf := []byte(msg)
        // запись (передача) в соединение
        _, err = conn.Write(buf)
        if err != nil {
            log.Fatal(err)
        }
        // 1 секундочку
        time.Sleep(time.Second * 1)
    }
}

Pouzdan prenos podataka preko kanala sa mogućim greškama

Sljedeći korak je pretpostaviti da se svi poslani paketi primaju redoslijedom kojim su poslani, ali bitovi u njima mogu biti oštećeni zbog činjenice da kanal ponekad prenosi podatke sa izobličenjem.

Osnove pouzdanog prijenosa podataka

U ovom slučaju koriste se sljedeći mehanizmi:

  • detekcija grešaka;
  • povratne informacije;
  • retransmisija.

Pouzdani protokoli za prijenos podataka koji imaju slične mehanizme za ponavljanje prijenosa više puta nazivaju se protokoli zahtjeva za automatsko ponavljanje (ARQ).
Osim toga, vrijedno je razmotriti mogućnost grešaka u prijemu, kada strana koja prima neće dobiti nikakvu informaciju o rezultatima prijenosa posljednjeg paketa.
Rješenje ovog problema, koje se također koristi u TCP-u, je dodavanje novog polja u paket podataka koje sadrži redni broj paketa.

Osnove pouzdanog prijenosa podataka

Pouzdan prenos podataka preko nepouzdanog kanala podložan izobličenju i gubitku paketa

Uz izobličenje, nažalost, dolazi i do gubitka paketa u mreži.
A za rješavanje ovog problema potrebni su mehanizmi:

  • utvrđivanje činjenice gubitka paketa;
  • ponovna dostava izgubljenih paketa strani primaocu.

Dodatno, pored gubitka paketa, potrebno je predvidjeti mogućnost gubitka računa ili, ako ništa nije izgubljeno, njegovu dostavu sa značajnim zakašnjenjem. U svim slučajevima radi se ista stvar: paket se ponovo prenosi. Za kontrolu vremena, ovaj mehanizam koristi tajmer za odbrojavanje, koji vam omogućava da odredite kraj intervala čekanja. Dakle u paketu neto TCPKeepAlive je po defaultu postavljen na 15 sekundi:

// defaultTCPKeepAlive is a default constant value for TCPKeepAlive times
// See golang.org/issue/31510
const (
    defaultTCPKeepAlive = 15 * time.Second
)

Strana koja šalje treba da pokrene tajmer svaki put kada se paket prenese (i prvi i drugi put), obradi prekide tajmera i zaustavi ga.

Dakle, upoznali smo se s ključnim konceptima pouzdanih protokola za prijenos podataka:

  • kontrolne sume;
  • redni brojevi paketa;
  • tajmeri;
  • pozitivne i negativne račune.

Ali to nije sve!

Pouzdan protokol za prijenos podataka s cjevovodom

U varijanti koju smo već razmatrali, pouzdan protokol isporuke je vrlo neefikasan. Počinje da „usporava“ prenos koji obezbeđuje komunikacijski kanal kako se RTT povećava. Da bi se povećala njegova efikasnost i bolje iskoristio kapacitet komunikacijskog kanala, koristi se cjevovod.

Osnove pouzdanog prijenosa podataka

Upotreba cjevovoda dovodi do:

  • povećanje opsega redoslednih brojeva, pošto svi poslani paketi (osim retransmisije) moraju biti jedinstveno identifikovani;
  • potreba za povećanjem bafera na strani koja prenosi i prima.

Zahtjevi za raspon brojeva sekvence i veličinu bafera zavise od akcija koje protokol poduzima kao odgovor na oštećenje, gubitak i kašnjenje paketa. U slučaju cjevovoda, postoje dvije metode za ispravljanje grešaka:

  • vratiti N paketa nazad;
  • selektivno ponavljanje.

Povratak N paketa - protokol kliznog prozora

Osnove pouzdanog prijenosa podataka

Pošiljalac mora podržavati tri vrste događaja:

  • poziva po protokolu višeg nivoa. Kada se funkcija slanja podataka pozove „odozgo“, strana koja šalje prvo proverava stepen popunjenosti prozora (tj. prisustvo N poslanih poruka koje čekaju prijem potvrda). Ako je prozor prazan, novi paket se generira i prenosi, a vrijednosti varijabli se ažuriraju. U suprotnom, strana koja šalje podatke vraća podatke u gornji sloj, a to je implicitna indikacija da je prozor pun. Obično će gornji sloj pokušati ponovo prenijeti podatke nakon nekog vremena. U stvarnoj aplikaciji, pošiljalac bi vjerovatno ili baferovao podatke (umjesto da ih odmah pošalje) ili bi imao mehanizam sinhronizacije (kao što je semafor ili zastavica) koji bi omogućio gornjem sloju da pozove funkciju slanja samo kada je prozor prazan .
  • prima potvrdu. U protokolu, za paket sa rednim brojem N, izdaje se opšta potvrda koja pokazuje da su svi paketi sa rednim brojevima koji prethode N uspešno primljeni.
  • interval čekanja je istekao. Za utvrđivanje činjenica gubitaka i kašnjenja paketa i prijema, protokol koristi tajmer. Ako istekne vremensko ograničenje, strana koja šalje ponovo šalje sve poslane nepotvrdjene pakete.

Selektivno ponavljanje

Kada su veličina prozora i proizvod kašnjenja propusnosti-propagacije veliki, veliki broj paketa može biti u cjevovodu. U takvom slučaju, greška u jednom paketu može uzrokovati ponovni prijenos velikog broja paketa, od kojih većina nije bila potrebna.

Primjer:

Lučšie teorijski prakse se prikupljaju u praktičnoj implementaciji TCP. A ako neko zna kako najbolje - dobrodošli.

Server

package main

import (
    "bufio"
    "fmt"
    "log"
    "net"
    "strings"
)

func main() {
    // создаем сокет с портом 
    ln, err := net.Listen("tcp", ":8081")
    if err != nil {
        log.Fatalln(err)
    }
    // ожидание вызова
    conn, _ := ln.Accept()

    for {
        // считывание данных
        msg, err := bufio.NewReader(conn).ReadString('n')
        if err != nil {
            log.Fatalln(err)
        }
        // вывод сообщения в stdout
        fmt.Print("Message Received:", string(msg))
        // перевод строки в верхний регистр
        newMsg := strings.ToUpper(msg)
        // отправка данных
        conn.Write([]byte(newMsg + "n"))
    }
}

Kupac

package main

import (
    "bufio"
    "fmt"
    "log"
    "net"
    "os"
)

func main() {
    // установка соединения
    conn, err := net.Dial("tcp", "127.0.0.1:8081")
    if err != nil {
        log.Fatalln(err)
    }

    for {
        // считывание данных с stdin
        reader := bufio.NewReader(os.Stdin)
        fmt.Print("Text to send: ")
        // построчно
        text, err := reader.ReadString('n')
        if err != nil {
            log.Fatalln(err)
        }
        // отправка
        fmt.Fprintf(conn, text+"n")
        // прием
        msg, err := bufio.NewReader(conn).ReadString('n')
        if err != nil {
            log.Fatalln(err)
        }
        // вывод полученного ответа
        fmt.Print("Msg from Server: " + msg)
    }
}

zaključak

Mehanizmi koji osiguravaju pouzdan prijenos i korištenje podataka

Mehanizam
Prijava, komentar

Čekovni zbroj
Koristi se za otkrivanje grešaka bitova u prenesenom paketu

Tajmer
Odbrojava vremenski interval i pokazuje kada je istekao. Ovo poslednje znači da se sa velikim stepenom verovatnoće paket ili njegov prijem izgubi tokom prenosa. Ako je paket isporučen sa zakašnjenjem, ali nije izgubljen (prerano istekao interval vremenskog ograničenja), ili je račun izgubljen, ponovni prijenos vodi do duplikata paketa na strani primaoca

Serijski broj
Koristi se za sekvencijalno numerisanje paketa podataka koji se prenose od pošiljaoca do primaoca. Praznine u redoslijedu primljenih paketa omogućavaju primaocu da otkrije gubitak paketa. Isti redni brojevi paketa znače da su paketi duplikati jedan drugog

Potvrda
Generirano od strane primaoca i ukazuje na kraj koji šalje da je odgovarajući paket ili grupa paketa uspješno primljena. Obično potvrda sadrži redovne brojeve uspješno primljenih paketa. U zavisnosti od protokola, razlikuju se pojedinačne i grupne potvrde

Negativna potvrda
Koristi se od strane primaoca da obavesti pošiljaoca da je paket pogrešno primljen. Negativna potvrda obično uključuje redni broj paketa koji nije ispravno primljen

Prozor, transportna traka
Ograničite raspon brojeva sekvence koji se mogu koristiti za prijenos paketa. Multicast i rukovanje mogu značajno povećati protok protokola u poređenju sa čekanjem na potvrde. Kao što ćemo vidjeti, veličina prozora se može izračunati na osnovu mogućnosti prijema i baferiranja na prijemnoj strani, kao i na nivou opterećenja mreže

Više primjera korištenja Go za umrežavanje

В spremišta.

izvor: www.habr.com

Dodajte komentar