Fundamentals vun zouverlässeg Daten Transfert

Fundamentals vun zouverlässeg Daten Transfert

Fir déi, déi sicht Engagéiert fir Netzwierker a Protokoller ze verstoen.

Kuerz gefrot

Den Artikel diskutéiert d'Basis vun zouverléissege Dateniwwerdroung, implementéiert Beispiller op Go, dorënner UDP an TCP. Baséiert op Zäiten, два, dräi an d'Bicher "Computer Networks. Top-Down Approach", soss diskutéiert jiddereen nëmmen Tannenbaum an Oliferov.

Transport Layer Protokoll

Bitt eng logesch Verbindung tëscht Applikatiounsprozesser déi op verschiddene Hosten lafen. Aus enger Applikatiounsperspektiv gesäit eng logesch Verbindung aus wéi e Kanal deen Prozesser direkt verbënnt.

Fundamentals vun zouverlässeg Daten Transfert

Transport Layer Protokoller ginn vun Endsystemer ënnerstëtzt, awer net vun Netzwierkrouter (ausser - dpi). Op der Sender Säit konvertéiert d'Transportschicht d'Applikatiounsschichtdaten, déi se vum Sendeapplikatiounsprozess kritt, an Transportschichtpakete genannt Segmenter.

Fundamentals vun zouverlässeg Daten Transfert

Dëst gëtt gemaach andeems Dir (wann néideg) d'Applikatiounsschicht Messagen a Fragmenter opdeelt an en Transportschichtheader un all eenzel bäidréit.

Fundamentals vun zouverlässeg Daten Transfert

D'Transportschicht passéiert dann de Segment un d'Netzschicht vum Sender, wou de Segment an engem Netzwierkschichtpaket (Datagram) agespaart gëtt a geschéckt gëtt. Um Empfangsend extrahéiert d'Netzschicht den Transportschichtsegment aus dem Datagram a passéiert et op d'Transportschicht. Als nächst veraarbecht d'Transportschicht de kritt Segment sou datt seng Donnéeën zur Empfangsapplikatioun verfügbar sinn.

Fundamentals vun zouverlässeg Daten Transfert

Prinzipien vun zouverlässeg Daten Transmissioun

Zouverlässeg Dateniwwerdroung iwwer e komplett séchere Kanal

Am einfachsten Fall. D'Sendsäit kritt einfach d'Donnéeën vun der ieweschter Schicht, erstellt e Paket deen et enthält a schéckt se op de Kanal.

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

Client

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

Zouverlässeg Dateniwwerdroung iwwer e Kanal mat méigleche Feeler

De nächste Schrëtt ass unzehuelen datt all iwwerdroe Pakete an der Uerdnung opgeholl ginn an där se geschéckt goufen, awer d'Bits an hinnen kënne korrupt sinn wéinst der Tatsaach datt de Kanal heiansdo Daten mat Verzerrungen iwwerdréit.

Fundamentals vun zouverlässeg Daten Transfert

An dësem Fall ginn déi folgend Mechanismen benotzt:

  • Feeler Detektioun;
  • Feedback;
  • retransmission.

Zouverlässeg Datenübertragungsprotokoller déi ähnlech Mechanismen hunn fir d'Transmissioun méi Mol ze widderhuelen, ginn Automatesch Repeat reQuest (ARQ) Protokoller genannt.
Zousätzlech ass et derwäert ze berücksichtegen d'Méiglechkeet vu Feeler an den Empfangen, wann d'Empfänger keng Informatioun iwwer d'Resultater vum Transfert vum leschte Paket kritt.
D'Léisung fir dëse Problem, och am TCP benotzt, ass en neit Feld un den Datepaket ze addéieren deen d'Sequenznummer vum Paket enthält.

Fundamentals vun zouverlässeg Daten Transfert

Zuverlässeg Dateniwwerdroung iwwer en onzouverlässeg Kanal ënnerleien Paketverzerrung a Verloscht

Zesumme mat Verzerrung gëtt et leider Paketverloscht am Netz.
A fir dëse Problem ze léisen, sinn Mechanismen néideg:

  • Bestëmmung vun der Tatsaach vum Paketverloscht;
  • Re-Liwwerung vu verluerene Päckchen un déi empfaang Partei.

Zousätzlech, zousätzlech zum Verloscht vum Package, ass et néideg fir d'Méiglechkeet vum Verloscht vum Empfang ze garantéieren oder, wann näischt verluer ass, seng Liwwerung mat engem wesentleche Verspéidung. An alle Fäll gëtt datselwecht gemaach: de Paket gëtt nei iwwerdroen. Fir d'Zäit ze kontrolléieren, benotzt dëse Mechanismus e Countdown Timer, deen Iech erlaabt d'Enn vum Waardeintervall ze bestëmmen. Also am Package net TCPKeepAlive ass standardiséiert op 15 Sekonnen:

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

D'Sendsäit muss en Timer starten all Kéier wann e Paket iwwerdroe gëtt (souwuel déi éischt an déi zweet Kéier), Ënnerbriechungen vum Timer handhaben a stoppen.

Also hu mir d'Schlësselkonzepter vun zouverléissege Datentransferprotokoller vertraut:

  • Kontrollsummen;
  • Sequenznummeren vu Packagen;
  • Timer;
  • positiv an negativ Recetten.

Mee dat ass net alles!

Zouverlässeg Datenübertragungsprotokoll mat Pipelining

An der Variant, déi mir scho berücksichtegt hunn, ass den zouverléissege Liwwerprotokoll ganz ineffizient. Et fänkt un d'Transmissioun vun der Kommunikatiounskanal ze "verlueren" wéi d'RTT eropgeet. Fir seng Effizienz ze erhéijen an d'Kommunikatiounskanalkapazitéit besser ze notzen, gëtt Pipelining benotzt.

Fundamentals vun zouverlässeg Daten Transfert

D'Benotzung vu Pipelining féiert zu:

  • d'Erhéijung vun der Palette vun de Sequenznummeren, well all geschéckt Pakete (ausser fir Retransmissionen) muss eenzegaarteg identifizéiert ginn;
  • de Besoin fir Puffer op der Sender- an Empfangssäit ze erhéijen.

D'Sequenznummerberäich an d'Puffergréisst Ufuerderunge hänkt vun den Aktiounen of, déi de Protokoll hëlt an Äntwert op Paketkorruptioun, Verloscht a Verzögerung. Am Fall vu Pipelining ginn et zwou Methoden fir Feeler ze korrigéieren:

  • zréck N Pakete zréck;
  • selektiv Widderhuelung.

Zréckgoen N Pakete - rutscht Fënster Protokoll

Fundamentals vun zouverlässeg Daten Transfert

De Sender muss dräi Aarte vun Eventer ënnerstëtzen:

  • ruffen mat engem méi héije Protokoll. Wann d'Date-Sendfunktioun "vun uewen" genannt gëtt, iwwerpréift d'Sendsäit fir d'éischt de Füllgrad vun der Fënster (dat ass d'Präsenz vun N geschéckte Messagen déi op d'Empfang vun de Empfang waarden). Wann d'Fënster eidel ass, gëtt en neie Paket generéiert an iwwerdroen, an d'Variabel Wäerter ginn aktualiséiert. Soss gëtt d'Send Säit Daten op déi iewescht Schicht zréck, an dëst ass eng implizit Indikatioun datt d'Fënster voll ass. Normalerweis probéiert déi iewescht Schicht d'Donnéeën no enger Zäit erëm ze vermëttelen. An enger realer Applikatioun wäert de Sender wahrscheinlech entweder d'Daten bufferen (amplaz se direkt ze schécken) oder e Synchroniséierungsmechanismus hunn (wéi e Semaphore oder Fändel) deen et erlaabt datt déi iewescht Schicht d'Sendfunktioun nëmmen ruffe wann d'Fënster eidel ass .
  • kréien Confirmatiouns. Am Protokoll, fir e Paket mat der Sequenznummer N, gëtt eng allgemeng Unerkennung erausginn, déi beweist datt all Pakete mat Sequenznummeren viru N erfollegräich opgeholl goufen.
  • d'Waardeintervall ass ofgelaf. Fir d'Fakten vu Verloschter a Verspéidungen vu Paketen a Empfangen ze bestëmmen, benotzt de Protokoll en Timer. Wann den Timeout-Intervall ofleeft, schéckt d'Sendsäit all geschéckt net unerkannt Pakete nei.

Selektiv Widderhuelung

Wann d'Fënstergréisst an d'Duerchgang-Verbreedungsverzögerungsprodukt grouss sinn, kann eng grouss Zuel vu Päck an der Pipeline sinn. An esou engem Fall kann en eenzege Paketfehler verursaachen datt eng grouss Zuel vu Pakete weidergeleet ginn, déi meescht vun deenen net erfuerderlech waren.

Beispill:

Déi bescht theoretesch Praktiken ginn an der praktescher Ëmsetzung gesammelt TCP. A wann een weess wéi am beschten - Wëllkomm.

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

Client

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

Konklusioun

Mechanismen fir zouverlässeg Datentransfer a Gebrauch ze garantéieren

Механизм
Bewerbung, Kommentar

Zomm kontrolléieren
Benotzt fir Bitfehler an engem iwwerdroe Paket z'entdecken

Timer
Zielt den Timeout-Intervall erof a weist un wéini et ofgelaf ass. Dat lescht bedeit datt mat engem héije Grad vu Wahrscheinlechkeet de Pak oder seng Empfang während der Iwwerdroung verluer geet. Wann e Paket mat enger Verzögerung geliwwert gëtt, awer net verluer ass (virzäitegen Oflaf vum Timeout-Intervall), oder e Empfang verluer ass, féiert d'Wiedertransmissioun zu engem Duplikat Paket op der Empfangssäit

Seriennummer
Benotzt fir sequentiell Nummeréierung vun Datepäck, déi vum Sender un den Empfänger iwwerdroe ginn. Lücken an der Sequenznummeren vun de empfangene Pakete erlaben den Empfänger Paketverloscht z'entdecken. Déi selwecht Paket Sequenznummeren bedeiten datt d'Päck Duplikate vuneneen sinn

Bestätegung
Generéiert vum Empfangsend a beweist dem Sendend Enn datt de entspriechende Paket oder Grupp vu Paketen erfollegräich opgeholl gouf. Typesch enthält d'Unerkennung d'Sequenznummeren vun erfollegräich empfangene Pakete. Ofhängeg vum Protokoll ginn individuell a Grupp Bestätegungen ënnerscheet

Negativ Bestätegung
Benotzt vum Empfänger fir de Sender z'informéieren datt de Paket falsch opgeholl gouf. Eng negativ Unerkennung enthält normalerweis d'Sequenznummer vum Paket deen net korrekt kritt gouf

Fënster, conveyorization
Limitéiert d'Gamme vu Sequenznummeren déi benotzt kënne fir Päck ze vermëttelen. Multicast an Handshake kënnen de Protokollduerchgang wesentlech erhéijen am Verglach zum Waarden op Unerkennungen. Wéi mir wäerte gesinn, kann d'Fënstergréisst berechent ginn op Basis vun den Empfangs- a Pufferfäegkeeten vum Empfangsend, souwéi dem Netzbelaaschtungsniveau

Méi Beispiller fir Go fir Netzwierker ze benotzen

В Repositories.

Source: will.com

Setzt e Commentaire