Osnove zanesljivega prenosa podatkov

Osnove zanesljivega prenosa podatkov

Tistim, ki išče Predan razumevanju omrežij in protokolov.

Na kratko

Članek obravnava osnove zanesljivega prenosa podatkov, implementira primere Go, vključno z UDP in TCP. Temelji na čas, два, 3 in knjige "Računalniška omrežja. Pristop od zgoraj navzdol", drugače vsi razpravljajo samo o Tannenbaumu in Oliferovu.

Protokol transportne plasti

Zagotavlja logično povezavo med aplikacijskimi procesi, ki se izvajajo na različnih gostiteljih. Z vidika aplikacije je logična povezava videti kot kanal, ki neposredno povezuje procese.

Osnove zanesljivega prenosa podatkov

Protokoli transportne plasti podpirajo končni sistemi, ne pa tudi omrežni usmerjevalniki (razen - DPI). Na strani pošiljatelja transportna plast pretvori podatke aplikacijske plasti, ki jih prejme od procesa pošiljajoče aplikacije, v pakete transportne plasti, imenovane segmenti.

Osnove zanesljivega prenosa podatkov

To se naredi tako, da se (če je potrebno) sporočila aplikacijskega sloja razdeli na fragmente in se vsakemu od njih doda glava transportnega sloja.

Osnove zanesljivega prenosa podatkov

Transportna plast nato posreduje segment pošiljateljevemu omrežnemu sloju, kjer se segment enkapsulira v paket omrežne plasti (datagram) in pošlje. Na sprejemnem koncu omrežna plast ekstrahira segment transportne plasti iz datagrama in ga posreduje transportni plasti. Nato transportna plast obdela prejeti segment, tako da njegovi podatki postanejo na voljo prejemni aplikaciji.

Osnove zanesljivega prenosa podatkov

Načela zanesljivega prenosa podatkov

Zanesljiv prenos podatkov po popolnoma varnem kanalu

Najenostavnejši primer. Stran pošiljatelja preprosto prejme podatke iz zgornje plasti, ustvari paket, ki jih vsebuje, in jih pošlje kanalu.

Strežnik

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 + надежный канал
    }
}

Stranka

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)
    }
}

Zanesljiv prenos podatkov po kanalu z možnimi napakami

Naslednji korak je domneva, da so vsi poslani paketi prejeti v vrstnem redu, v katerem so bili poslani, vendar so lahko biti v njih poškodovani zaradi dejstva, da kanal včasih prenaša podatke s popačenjem.

Osnove zanesljivega prenosa podatkov

V tem primeru se uporabljajo naslednji mehanizmi:

  • odkrivanje napak;
  • povratne informacije;
  • retransmisija.

Zanesljivi protokoli za prenos podatkov, ki imajo podobne mehanizme za večkratno ponavljanje prenosa, se imenujejo protokoli za samodejno ponavljanje zahteve (ARQ).
Poleg tega je vredno razmisliti o možnostih napak v potrdilih, ko prejemnik ne bo prejel nobenih informacij o rezultatih prenosa zadnjega paketa.
Rešitev te težave, ki se uporablja tudi v TCP, je dodajanje novega polja podatkovnemu paketu, ki vsebuje zaporedno številko paketa.

Osnove zanesljivega prenosa podatkov

Zanesljiv prenos podatkov po nezanesljivem kanalu, ki je podvržen popačenju in izgubi paketov

Skupaj z izkrivljanjem na žalost prihaja do izgube paketov v omrežju.
In za rešitev tega problema so potrebni mehanizmi:

  • ugotavljanje dejstva izgube paketa;
  • ponovna dostava izgubljenih paketov prejemniku.

Dodatno je treba poleg izgube paketa predvideti tudi možnost izgube potrdila ali, če se nič ne izgubi, njegove dostave s precejšnjo zamudo. V vseh primerih se izvede isto: paket se ponovno pošlje. Za nadzor časa ta mehanizem uporablja odštevalnik časa, ki vam omogoča, da določite konec čakalnega intervala. Torej v paketu net TCPKeepAlive je privzeto nastavljen na 15 sekund:

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

Stran pošiljateljica mora zagnati časovnik ob vsakem prenosu paketa (tako prvič kot drugič), obravnavati prekinitve časovnika in ga ustaviti.

Tako smo se seznanili s ključnimi pojmi zanesljivih protokolov za prenos podatkov:

  • kontrolne vsote;
  • zaporedne številke paketov;
  • časovniki;
  • pozitivne in negativne prejemke.

A to še ni vse!

Zanesljiv protokol za prenos podatkov s cevovodom

V varianti, ki smo jo že obravnavali, je zanesljiv protokol dostave zelo neučinkovit. Ko se RTT poveča, začne "upočasnjevati" prenos, ki ga zagotavlja komunikacijski kanal. Za povečanje njegove učinkovitosti in boljši izkoristek zmogljivosti komunikacijskega kanala se uporablja cevovod.

Osnove zanesljivega prenosa podatkov

Uporaba cevovoda vodi do:

  • povečanje obsega zaporednih številk, saj morajo biti vsi poslani paketi (razen ponovnih prenosov) enolično identificirani;
  • potreba po povečanju medpomnilnikov na oddajni in sprejemni strani.

Obseg zaporednih številk in zahteve glede velikosti vmesnega pomnilnika so odvisne od dejanj, ki jih protokol izvede kot odgovor na poškodovanje paketa, izgubo in zamudo. V primeru cevovoda obstajata dva načina za popravljanje napak:

  • vrni N paketov nazaj;
  • selektivno ponavljanje.

Nazaj N paketov - protokol drsnega okna

Osnove zanesljivega prenosa podatkov

Pošiljatelj mora podpirati tri vrste dogodkov:

  • klic po protokolu višje ravni. Ko je funkcija pošiljanja podatkov poklicana »od zgoraj«, pošiljateljica najprej preveri stopnjo zapolnjenosti okna (to je prisotnost N poslanih sporočil, ki čakajo na prejem potrdil). Če je okno prazno, se ustvari in prenese nov paket, vrednosti spremenljivk pa se posodobijo. V nasprotnem primeru pošiljatelj vrne podatke v zgornjo plast, kar je impliciten znak, da je okno polno. Običajno bo zgornja plast čez nekaj časa znova poskušala prenesti podatke. V resnični aplikaciji bi pošiljatelj verjetno bodisi shranil podatke v medpomnilnik (namesto da bi jih takoj poslal) bodisi imel sinhronizacijski mehanizem (kot je semafor ali zastavica), ki bi zgornjemu sloju omogočil, da pokliče funkcijo pošiljanja le, ko je okno prazno .
  • prejemanje potrditve. V protokolu se za paket z zaporedno številko N izda splošna potrditev, ki označuje, da so bili vsi paketi z zaporedno številko pred N uspešno prejeti.
  • čakalni interval je potekel. Za ugotavljanje dejstev o izgubah in zamudah pri paketih in potrdilih protokol uporablja časovnik. Če interval časovne omejitve poteče, stran pošiljateljica ponovno pošlje vse poslane nepotrjene pakete.

Selektivno ponavljanje

Ko sta velikost okna in produkt zakasnitve širjenja prepustnosti velika, je lahko v cevovodu veliko število paketov. V takem primeru lahko ena napaka paketa povzroči ponovno pošiljanje velikega števila paketov, od katerih večina ni bila potrebna.

Primer

Top teoretično prakse so zbrane v praktični izvedbi TCP. In če kdo ve, kako najbolje - dobrodošli.

Strežnik

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"))
    }
}

Stranka

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)
    }
}

Izhod

Mehanizmi za zagotavljanje zanesljivega prenosa in uporabe podatkov

Mehanizem
Prijava, komentar

Kontrolna vsota
Uporablja se za odkrivanje bitnih napak v poslanem paketu

Časovnik
Odšteva interval časovne omejitve in prikazuje, kdaj je potekel. Slednje pomeni, da se paket ali potrdilo o njegovem sprejemu med prenosom z veliko verjetnostjo izgubi. Če je paket dostavljen z zakasnitvijo, vendar ni izgubljen (prezgodnji iztek časovne omejitve) ali je potrdilo o prejemu izgubljeno, ponovni prenos vodi do podvojenega paketa na sprejemni strani

Serijska številka
Uporablja se za zaporedno številčenje podatkovnih paketov, ki se prenašajo od pošiljatelja do prejemnika. Vrzeli v zaporednih številkah prejetih paketov omogočajo sprejemniku, da zazna izgubo paketa. Enake zaporedne številke paketov pomenijo, da so paketi dvojniki drug drugega

Potrditev
Generira ga prejemni konec in pošiljatelju nakazuje, da je bil ustrezen paket ali skupina paketov uspešno prejet. Običajno potrditev vsebuje zaporedne številke uspešno prejetih paketov. Glede na protokol ločimo individualne in skupinske potrditve

Negativna potrditev
Uporablja ga prejemnik, da obvesti pošiljatelja, da je bil paket prejet nepravilno. Negativna potrditev običajno vključuje zaporedno številko paketa, ki ni bil pravilno prejet

Okno, transport
Omejite obseg zaporednih številk, ki se lahko uporabljajo za prenos paketov. Multicast in rokovanje lahko znatno povečata prepustnost protokola v primerjavi s čakanjem na potrditve. Kot bomo videli, je mogoče velikost okna izračunati na podlagi zmogljivosti sprejema in medpomnjenja sprejemnega konca ter stopnje obremenitve omrežja.

Več primerov uporabe Go za mreženje

В repozitorije.

Vir: www.habr.com

Dodaj komentar