Основе поузданог преноса података

Основе поузданог преноса података

Онима који тражи Посвећен разумевању мрежа и протокола.

Укратко

Чланак говори о основама поузданог преноса података, имплементира примере на Go, укључујући УДП и ТЦП. На бази време, два, три и књиге "Рачунарске мреже. Приступ одозго надоле", иначе сви расправљају само о Таненбауму и Олиферову.

Протокол транспортног слоја

Обезбеђује логичку везу између процеса апликације који се покрећу на различитим хостовима. Из перспективе апликације, логичка веза изгледа као канал који директно повезује процесе.

Основе поузданог преноса података

Протоколи транспортног слоја подржавају крајњи системи, али не и мрежни рутери (осим - ДПИ). На страни пошиљаоца, транспортни слој конвертује податке слоја апликације које прима од процеса слања апликације у пакете транспортног слоја који се називају сегменти.

Основе поузданог преноса података

Ово се ради раздвајањем (ако је потребно) порука слоја апликације на фрагменте и додавањем заглавља транспортног слоја сваком од њих.

Основе поузданог преноса података

Транспортни слој затим прослеђује сегмент мрежном слоју пошиљаоца, где се сегмент инкапсулира у пакет мрежног слоја (датаграм) и шаље. На крају пријема, мрежни слој издваја сегмент транспортног слоја из датаграма и прослеђује га транспортном слоју. Затим, транспортни слој обрађује примљени сегмент тако да његови подаци постају доступни апликацији која прима.

Основе поузданог преноса података

Принципи поузданог преноса података

Поуздан пренос података преко потпуно безбедног канала

Најједноставнији случај. Страна која шаље податке једноставно прима податке са горњег слоја, креира пакет који их садржи и шаље га каналу.

Сервер

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

Цустомер

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

Поуздан пренос података преко канала са могућим грешкама

Следећи корак је претпоставити да се сви послани пакети примају редоследом којим су послати, али битови у њима могу бити оштећени због чињенице да канал понекад преноси податке са изобличењем.

Основе поузданог преноса података

У овом случају користе се следећи механизми:

  • откривање грешке;
  • повратна информација;
  • ретрансмисија.

Поуздани протоколи за пренос података који имају сличне механизме за вишеструко понављање преноса називају се протоколи са аутоматским захтевом за понављање (АРК).
Поред тога, вреди размотрити могућност грешака у пријему, када страна која прима неће добити никакву информацију о резултатима преноса последњег пакета.
Решење овог проблема, које се такође користи у ТЦП-у, је додавање новог поља у пакет података које садржи редни број пакета.

Основе поузданог преноса података

Поуздан пренос података преко непоузданог канала подложан изобличењу и губитку пакета

Уз изобличење, нажалост, постоји и губитак пакета у мрежи.
А да би се решио овај проблем, потребни су механизми:

  • утврђивање чињенице губитка пакета;
  • поновна достава изгубљених пакета страни примаоцу.

Додатно, поред губитка пакета, потребно је предвидети могућност губитка рачуна или, ако ништа није изгубљено, његову испоруку са значајним закашњењем. У свим случајевима се ради исто: пакет се поново преноси. За контролу времена, овај механизам користи тајмер за одбројавање, који вам омогућава да одредите крај интервала чекања. Дакле у пакету нето ТЦПКеепАливе је подразумевано подешен на 15 секунди:

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

Страна која шаље треба да покрене тајмер сваки пут када се пакет пренесе (и први и други пут), да управља прекидима тајмера и да га заустави.

Дакле, упознали смо се са кључним концептима поузданих протокола за пренос података:

  • контролне суме;
  • редни бројеви пакета;
  • тајмери;
  • позитивних и негативних примања.

Али то није све!

Поуздан протокол за пренос података са цевоводом

У варијанти коју смо већ разматрали, поуздан протокол испоруке је веома неефикасан. Почиње да „успорава“ пренос који обезбеђује комуникациони канал како се РТТ повећава. Да би се повећала његова ефикасност и боље искористио капацитет комуникационог канала, користи се цевовод.

Основе поузданог преноса података

Употреба цевовода доводи до:

  • повећање опсега редоследних бројева, пошто сви послати пакети (осим ретрансмисија) морају бити јединствено идентификовани;
  • потреба за повећањем бафера на предајној и пријемној страни.

Захтеви за опсег бројева секвенце и величину бафера зависе од радњи које протокол предузима као одговор на оштећење, губитак и кашњење пакета. У случају цевовода, постоје две методе за исправљање грешака:

  • вратити Н пакета назад;
  • селективно понављање.

Повратак Н пакета - протокол клизног прозора

Основе поузданог преноса података

Пошиљалац мора да подржава три типа догађаја:

  • позива протоколом вишег нивоа. Када се функција слања података позове „одозго“, страна која шаље прво проверава степен попуњености прозора (тј. присуство Н послатих порука које чекају пријем потврда). Ако је прозор празан, нови пакет се генерише и преноси, а вредности променљивих се ажурирају. У супротном, страна која шаље податке враћа податке у горњи слој, а то је имплицитна индикација да је прозор пун. Обично ће горњи слој покушати поново да пренесе податке након неког времена. У стварној апликацији, пошиљалац би вероватно или баферовао податке (уместо да их одмах пошаље) или би имао механизам синхронизације (као што је семафор или заставица) који би омогућио горњем слоју да позове функцију слања само када је прозор празан .
  • примање потврде. У протоколу, за пакет са редним бројем Н, издаје се општа потврда која показује да су сви пакети са редним бројевима који претходе Н успешно примљени.
  • интервал чекања је истекао. За утврђивање чињеница губитака и кашњења пакета и пријема, протокол користи тајмер. Ако временско ограничење истекне, страна која шаље поново шаље све послате непотврдјене пакете.

Селективно понављање

Када су величина прозора и производ кашњења пропусности велики, велики број пакета може бити у цевоводу. У таквом случају, грешка у једном пакету може проузроковати поновни пренос великог броја пакета, од којих већина није била потребна.

Пример

Топ теоријски праксе се прикупљају у практичној примени ТЦП. А ако неко зна како најбоље - добродошао.

Сервер

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

Цустомер

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

Излаз

Механизми који обезбеђују поуздан пренос и коришћење података

Механизам
Пријава, коментар

Контролна сума
Користи се за откривање грешака битова у преношеном пакету

Тајмер
Одбројава интервал временског ограничења и показује када је истекао. Ово последње значи да се са великим степеном вероватноће пакет или његов пријем губи током преноса. Ако је пакет испоручен са закашњењем, али није изгубљен (преурањени истек интервала временског ограничења), или је пријем изгубљен, поновни пренос води до дупликата пакета на страни која прима

Серијски број
Користи се за секвенцијално нумерисање пакета података који се преносе од пошиљаоца до примаоца. Празнине у редоследним бројевима примљених пакета омогућавају пријемнику да открије губитак пакета. Исти редни бројеви пакета значе да су пакети дупликати један другог

Потврда
Генерисано од стране примаоца и указује на крај који шаље да је одговарајући пакет или група пакета успешно примљена. Обично потврда садржи редне бројеве успешно примљених пакета. У зависности од протокола, разликују се појединачне и групне потврде

Негативна потврда
Користи га прималац да обавести пошиљаоца да је пакет погрешно примљен. Негативна потврда обично укључује редни број пакета који није исправно примљен

Прозор, транспортна трака
Ограничите опсег бројева секвенце који се могу користити за пренос пакета. Мултицаст и руковање могу значајно повећати проток протокола у поређењу са чекањем на потврде. Као што ћемо видети, величина прозора се може израчунати на основу могућности пријема и баферовања пријемног краја, као и нивоа оптерећења мреже

Још примера коришћења Го за умрежавање

В спремишта.

Извор: ввв.хабр.цом

Додај коментар