Andmete usaldusvÀÀrse edastamise alused

Andmete usaldusvÀÀrse edastamise alused

Neile, kes pĂŒĂŒab soovivad mĂ”ista vĂ”rgustikke ja protokolle, on pĂŒhendatud.

LĂŒhidalt

Artiklis kĂ€sitletakse andmete usaldusvÀÀrse edastamise aluseid, tuuakse nĂ€iteid Go, sealhulgas UDP ja TCP. Inspireerituna ĂŒks, kaks, kolmest ja raamatust "ArvutivĂ”rgud. Ülemineku lĂ€henemine", kuna kĂ”ik rÀÀgivad ainult Tanenbaumist ja Oliferist.

Transpordiprotocol

Tagab loogilise ĂŒhenduse erinevates hostides toimivate rakendusprotsesside vahel. Rakenduste seisukohalt nĂ€eb loogiline ĂŒhendus vĂ€lja nagu kanal, mis ĂŒhendab protsessid otse.

Andmete usaldusvÀÀrse edastamise alused

Transpordiprotokollid on toetatud lĂ”pp-sĂŒsteemide poolt, kuid mitte vĂ”rgu marsruuterite poolt (vĂ€lja arvatud — DPI). Saatja poolel muundab transpordikiht rakendustaseme andmed, mille ta saab edastamise rakenduse protsessilt, transporditaseme pakettideks, mida nimetatakse segmentideks.

Andmete usaldusvÀÀrse edastamise alused

See toimub rakendustaseme sÔnumite vajadusel killustamise ja igale neist transporditaseme pÀise lisamise kaudu.

Andmete usaldusvÀÀrse edastamise alused

SeejĂ€rel edastab transpordikiht segmendi saatja vĂ”rgu kihile, kus segment kapseldatakse vĂ”rgu taseme paketti (datagrammi) ja saadetakse vĂ€lja. VastuvĂ”tva poole vĂ”rgu kiht ekstraktib transporditaseme segmendi datagrammist ja edastab selle ĂŒles transporditasemele. Edasi töötleb transpordikiht saadud segmenti nii, et selle andmed muutuvad vastuvĂ”tvale rakendusele kergesti kĂ€tte saadavaks.

Andmete usaldusvÀÀrse edastamise alused

UsaldusvÀÀrse andmeedastuse pÔhimÔtted

UsaldusvÀÀrne andmeedastus tÀiesti usaldusvÀÀrses kanal

Lihtsaim juhtum. Saatja poolel vĂ”etakse andmed ĂŒlalt, luuakse nendes sisalduv pakett ja saadetakse see kanalisse.

Server

package main

import (
    "log"
    "net"
)

func main() {
    // Serveri IP-aadress ja port
    serverAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:12000")
    if err != nil {
        log.Fatal(err)
    }

    // Loo sokkel porti jaoks
    serverConn, err := net.ListenUDP("udp", serverAddr)
    if err != nil {
        log.Fatal(err)
    }
    // Edasi lĂŒkatud ĂŒhenduse sulgemine
    defer serverConn.Close()

    // Loome andmepuhvri
    buf := make([]byte, 1024)

    // Ootame ĂŒhendust
    for {
        // Loeme pÀringut
        n, addr, err := serverConn.ReadFromUDP(buf)
        // Edastame andmed ÜLSEMISKIHTI: meie juhul stdout
        println(string(buf[0:n]), " forma ", addr.IP.String())
        if err != nil {
            log.Fatal(err)
        }
        // Vastust ei ole, kuna see on UDP + usaldusvÀÀrne kanal
    }
}

Kliendi

package main

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

func main() {
    // Serveri IP-aadress ja port
    serverAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:12000")
    if err != nil {
        log.Fatal(err)
    }
    // Kohalik IP-aadress ja port
    localAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0")
    if err != nil {
        log.Fatal(err)
    }
    // Ühenduse loomine
    conn, err := net.DialUDP("udp", localAddr, serverAddr)
    if err != nil {
        log.Fatal(err)
    }
    // Edasi lĂŒkatud ĂŒhenduse sulgemine
    defer conn.Close()

    for {
        // Andmete saamine ÜLSEMISKIHTILT
        fmt.Print("Sisestage lause > ")
        var msg string
        _, err := fmt.Scanf("%s", &msg)
        if err != nil {
            log.Fatal(err)
        }
        // Edastatakse baitide voog, mitte string
        buf := []byte(msg)
        // Kirjutamine (edastamine) ĂŒhendusse
        _, err = conn.Write(buf)
        if err != nil {
            log.Fatal(err)
        }
        // Üks sekund
        time.Sleep(time.Second * 1)
    }
}

UsaldusvÀÀrne andmete edastus kanalilt, kus vÔivad esineda vead

JÀrgmine etapp on eeldus, et kÔik edastatud paketid on saadud selles jÀrjekorras, milles need saadeti, kuid nendes olevad bitid vÔivad olla kahjustatud, kuna kanal edastab andmeid mÔnikord moonutustega.

Andmete usaldusvÀÀrse edastamise alused

Sellisel juhul rakendatakse mehhanisme:

  • vea avastamine;
  • tagasiside;
  • uuesti edastus.

UsaldusvÀÀrsete andmete edastusprotokollid, mis sisaldavad sarnaseid korduva edastuse mehhanisme, nimetatakse automaatse kordusnÔude (Automatic Repeat reQuest, ARQ) protokollideks.
Lisaks tuleks ette nÀha ka vigu ja vastuvÔtjate kviitungites, kui vastuvÔtja ei saa teavet viimase paketi edastamise tulemuste kohta.
Selle ĂŒlesande lahendus, mida kasutatakse ka TCP-s, seisneb andmepaketti uue vĂ€lja lisamises, mis sisaldab paketi jĂ€rjestuse numbrit.

Andmete usaldusvÀÀrse edastamise alused

UsaldusvÀÀrne andmete edastus usaldamatul kanalil, mis vÔimaldab moonutusi ja pakettide kadumist.

Kahjuks esinevad vÔrgu jooksul ka moonutused ja pakettide kaotus.
Ja selle probleemi lahendamiseks on vajalikud mehhanismid:

  • pakettide kaotuse tuvastamine;
  • kaotatud pakettide uuesti saatmine vastuvĂ”tjale.

Lisaks pakettide kadumisele tuleb arvestada ka kinnituste kadumise vÔimalusega vÔi, kui mitte midagi ei ole kadunud, selle edastamisega mÀrkimisvÀÀrse viivitusega. Igale juhtumile jÀrgneb sama tegevus: paketi kordussaatmine. Selle mehhanismi aja jÀlgimiseks kasutatakse tagasikutsumise taimerit, mis vÔimaldab mÀÀrata ooteintervalli lÔppu. Nii et pakettides net on TCPKeepAlive parameeter vaikimisi seatud 15 sekundiks:

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

Saatja peab kÀivitama taimeri iga kord paketi edastamisel (nii esmakordsel kui ka kordussaatmisel), töötlema taimerist saadud katkestusi ning peatama selle.

Nii oleme tutvunud usaldusvÀÀrse andmeedastuse protokollide pÔhikontseptsioonidega:

  • kontrollsummad;
  • pakettide jĂ€rjekorranumbrid;
  • taimerid;
  • positiivsed ja negatiivsed kinnitused.

Aga see ei ole kÔik!

UsaldusvÀÀrse andmeedastuse protokoll koos konveierimisega.

KÀesolevas variandis, mida oleme juba vaadanud, on usaldusvÀÀrse edastamise protokoll vÀga ebatÔhus. See hakkab viivitama edastust, mida toetab sidekanal, kui RTT suureneb. Selle tÔhususe suurendamiseks ja sidekanali lÀbilaskevÔime parema kasutuse jaoks rakendatakse konveierimist.

Andmete usaldusvÀÀrse edastamise alused

Konveierimise rakendamine toob kaasa:

  • jĂ€rjekorranumbrite piirkonna suurenemine, kuna kĂ”ik saadetavad paketid (vĂ€lja arvatud korduvad edastused) peavad olema selgelt tuvastatavad;
  • vajaduse suurendada mĂ€lupuhvrite mahtu saatja ja vastuvĂ”tja poolel.

JÀrjekorranumbrite vahemik ja mÀlupuhvrite suuruse nÔuded sÔltuvad protokolli tegevustest vastusena moonutusele, pakettide kadumisele ja viivitusele. Konveierimise puhul on kaks vigade parandamise meetodit:

  • tagasi N paketti;
  • valikuline kordus.

Tagasi N paketti — libiseva akna protokoll.

Andmete usaldusvÀÀrse edastamise alused

Saatjal peab olema kolm tĂŒĂŒpi sĂŒndmusi:

  • kĂ”rgema taseme protokolli kutse. Kui "ĂŒlemine" tasand kutsub andmete saatmise funktsiooni, kontrollib saatja esmalt akna tĂ€ituvust (st kas on olemas N saadetud sĂ”numit, mis ootavad kinnitusi). Kui aken ei ole tĂ€idetud, vormitakse ja edastatakse uus pakk, ning muutujate vÀÀrtused uuendatakse. Vastupidisel juhul tagastab saatja andmed ĂŒlemisele tasandile, mis on kaudne mĂ€rk, et aken on tĂ€idetud. TĂŒĂŒpiliselt ĂŒlemine tasand proovib andmete edastamist uuesti mĂ”ne aja pĂ€rast. Reaalses rakenduses oleks saatja tĂ”enĂ€oliselt kas andmeid vahemĂ€llu salvestanud (mitte kohe saatnud) vĂ”i omanud sĂŒnkroniseerimise mehhanismi (nĂ€iteks semafori vĂ”i lipu), mis vĂ”imaldaks ĂŒlemisel tasandil kutsuda andmete saatmise funktsiooni vaid siis, kui aken on tĂŒhi.
  • kinnituse saamine. Protokollis antakse pakett, mille jĂ€rjestuse number on N, ĂŒldine kinnitus, mis nĂ€itab, et kĂ”ik pakettide jĂ€rjestuse numbrid, mis on ettepoole N, on edukalt vastu vĂ”etud.
  • ootamisintervalli aegumine. Pakettide ja kinnituste kaotuste ning viivituste tuvastamiseks kasutab protokoll ajastusmeetrit. Kui ootamisintervall aegub, saadab saatja uuesti kĂ”ik saadetud kinnitamata paketid.

Valikuline kordamine

Kui akna suurus ja lĂ€bilaskevĂ”ime korrutatud leviaeg on suured, vĂ”ib torus olla palju pakette. Sellisel juhul vĂ”ib ĂŒhe paketi tĂ”rge pĂ”hjustada paljude pakettide korduvate edastamiste, millest enamus ei olnud vajalikud.

NĂ€ide

Parimad teoreetilised praktikad on kokku kogutud praktilises rakendamises TCP. Ja kui keegi teab, kuidas paremini — tere tulemast.

Server

package main

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

func main() {
    // loome soketi sadama 
    ln, err := net.Listen("tcp", ":8081")
    if err != nil {
        log.Fatalln(err)
    }
    // ootame kutset
    conn, _ := ln.Accept()

    for {
        // andmete lugemine
        msg, err := bufio.NewReader(conn).ReadString('n')
        if err != nil {
            log.Fatalln(err)
        }
        // sÔnumi vÀljund stdoutisse
        fmt.Print("SÔnum vastu vÔetud:", string(msg))
        // rea teisendamine suurte tÀhtedega
        newMsg := strings.ToUpper(msg)
        // andmete saatmine
        conn.Write([]byte(newMsg + "n"))
    }
}

Kliendi

pakett pÔhjas

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

func main() {
    // ĂŒhenduse loomine
    conn, err := net.Dial("tcp", "127.0.0.1:8081")
    if err != nil {
        log.Fatalln(err)
    }

    for {
        // andmete lugemine stdin'ist
        reader := bufio.NewReader(os.Stdin)
        fmt.Print("Saadetav tekst: ")
        // realt
        text, err := reader.ReadString('n')
        if err != nil {
            log.Fatalln(err)
        }
        // saatmine
        fmt.Fprintf(conn, text+"n")
        // vastuvÔtt
        msg, err := bufio.NewReader(conn).ReadString('n')
        if err != nil {
            log.Fatalln(err)
        }
        // saadud vastuse kuvamine
        fmt.Print("Serverilt sÔnum: " + msg)
    }
}

KokkuvÔte

Mehhanismid, mis tagavad usaldusvÀÀrse andme edastamise ja nende kasutamise

Mehhanism
Rakendus, kommentaar

Kontrollsumma
Kasutatakse edastatud paketi bitivigade tuvastamiseks

Taimer
Ooteintervalli mÔÔtmine ja selle lÔppemise nÀitamine. Viimane tÀhendab, et suure tÔenÀosusega on pakk vÔi selle kinnitamine edastamisel kaotsi lÀinud. Kui pakk saabub viivitusega, kuid mitte kaduma (enneaegne ooteintervalli lÔppemine), vÔi toimub kinnitamise kadu, toob uuesti edastamine kaasa pakettide dubleerimise vastuvÔtva poolel

JĂ€rjekorranumber
Kasutatakse andmepakettide jĂ€rjekorranumbrite numeerimiseks, mis edastatakse saatjalt vastuvĂ”tjale. PuudujÀÀgid saadud pakettide jĂ€rjekorranumbris vĂ”imaldavad vastuvĂ”tjal tuvastada pakettide kadumise. Sama jĂ€rjekorranumber tĂ€hendab, et paketid dubleerivad ĂŒksteist

Kinnitamine
Genereeritakse vastuvĂ”tva poole poolt ja nĂ€itab edastava poolele, et vastav pakk vĂ”i pakettide rĂŒhm on edukalt vastu vĂ”etud. Reeglina sisaldab kinnitamine edukalt vastu vĂ”etud pakettide jĂ€rjekorranumbrid. Olenevalt protokollist eristatakse individuaalseid ja grupi kinnitusi

Negatiivne kinnitamine
Kasutakse vastuvÔtja poolt saatjale teate edastamiseks, et pakk on saadud valesti. Negatiivne kinnitamine sisaldab tavaliselt jÀrjekorranumbrit paketti, mis ei ole korrektselt saadud

Aken, konveierimine
Piiravad kindlate jĂ€rjekorranumbrite vahemikku, mida saab pakkide edastamiseks kasutada. Grupiedastus ja kĂ€epigistus vĂ”imaldavad protokollide lĂ€bilaskevĂ”imet mĂ€rkimisvÀÀrselt suurendada vĂ”rreldes kinnituste ootamisreĆŸiimiga. Nagu me nĂ€eme, saab akna suurust arvutada vastuvĂ”tja poole vastuvĂ”tu- ja vahemĂ€luvĂ”imekuse ning vĂ”rgu koormuse taseme pĂ”hjal.

Teised nÀited Go kasutamisest vÔrgu tööks.

Uues hoidlad.

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster