Etibarlı məlumat ötürülməsinin əsasları

Etibarlı məlumat ötürülməsinin əsasları

edənlərə axtarır Şəbəkələri və protokolları başa düşməyə həsr edilmişdir.

Qısaca

Məqalədə etibarlı məlumat ötürülməsinin əsasları müzakirə olunur, nümunələr tətbiq olunur GoUDP və TCP daxil olmaqla. Əsasən vaxt, два, üç və "Kompüter şəbəkələri. Yuxarıdan aşağıya yanaşma" kitabları, əks halda hamı yalnız Tannenbaum və Oliferovu müzakirə edir.

Nəqliyyat qatının protokolu

Müxtəlif hostlarda işləyən tətbiq prosesləri arasında məntiqi əlaqəni təmin edir. Tətbiq baxımından məntiqi əlaqə prosesləri birbaşa birləşdirən kanal kimi görünür.

Etibarlı məlumat ötürülməsinin əsasları

Nəqliyyat qatının protokolları son sistemlər tərəfindən dəstəklənir, lakin şəbəkə marşrutlaşdırıcıları tərəfindən deyil (istisna - DPI). Göndərən tərəfdə nəqliyyat təbəqəsi göndərmə tətbiqi prosesindən aldığı tətbiq səviyyəsi məlumatlarını seqmentlər adlanan nəqliyyat qatı paketlərinə çevirir.

Etibarlı məlumat ötürülməsinin əsasları

Bu, tətbiq səviyyəsinin mesajlarını fraqmentlərə bölmək (lazım olduqda) və onların hər birinə nəqliyyat qatının başlığını əlavə etməklə həyata keçirilir.

Etibarlı məlumat ötürülməsinin əsasları

Daha sonra nəqliyyat təbəqəsi seqmenti göndərənin şəbəkə səviyyəsinə ötürür, burada seqment şəbəkə qatı paketinə (dataqram) daxil edilir və göndərilir. Qəbul edən tərəfdə şəbəkə səviyyəsi dataqramdan nəqliyyat təbəqəsi seqmentini çıxarır və onu nəqliyyat qatına ötürür. Sonra, nəqliyyat təbəqəsi qəbul edilmiş seqmenti emal edir ki, onun məlumatları qəbul edən proqram üçün əlçatan olsun.

Etibarlı məlumat ötürülməsinin əsasları

Etibarlı məlumat ötürülməsinin prinsipləri

Tamamilə təhlükəsiz kanal üzərindən etibarlı məlumat ötürülməsi

Ən sadə hal. Göndərən tərəf sadəcə olaraq yuxarı təbəqədən məlumatları qəbul edir, ondan ibarət paket yaradır və kanala göndərir.

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

Müştəri

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

Mümkün səhvlərlə bir kanal üzərindən etibarlı məlumat ötürülməsi

Növbəti addım, bütün ötürülən paketlərin göndərildiyi ardıcıllıqla qəbul edildiyini güman etməkdir, lakin kanalın bəzən məlumatları təhriflərlə ötürməsi səbəbindən onlarda olan bitlər pozula bilər.

Etibarlı məlumat ötürülməsinin əsasları

Bu vəziyyətdə aşağıdakı mexanizmlərdən istifadə olunur:

  • səhv aşkarlanması;
  • rəy;
  • təkrar ötürülmə.

Bir neçə dəfə təkrar ötürmə üçün oxşar mexanizmlərə malik olan etibarlı məlumat ötürmə protokolları Avtomatik Təkrar Sorğu (ARQ) protokolları adlanır.
Əlavə olaraq, qəbul edən tərəf son paketin ötürülməsinin nəticələri haqqında heç bir məlumat almadıqda qəbzlərdə səhvlərin olma ehtimalını nəzərə almağa dəyər.
TCP-də də istifadə edilən bu problemin həlli paketin ardıcıl nömrəsini ehtiva edən məlumat paketinə yeni sahə əlavə etməkdir.

Etibarlı məlumat ötürülməsinin əsasları

Paket təhrifinə və itkisinə məruz qalan etibarsız bir kanal üzərindən etibarlı məlumat ötürülməsi

Təhriflə yanaşı, təəssüf ki, şəbəkədə paket itkisi də var.
Və bu problemi həll etmək üçün mexanizmlər tələb olunur:

  • paketin itirilməsi faktının müəyyən edilməsi;
  • itirilmiş paketlərin qəbul edən tərəfə yenidən çatdırılması.

Bundan əlavə, bağlamanın itirilməsi ilə yanaşı, qəbzin itirilməsi və ya heç bir şey itirilməyibsə, əhəmiyyətli bir gecikmə ilə çatdırılması ehtimalını təmin etmək lazımdır. Bütün hallarda eyni şey edilir: paket yenidən ötürülür. Vaxta nəzarət etmək üçün bu mexanizm gözləmə intervalının sonunu müəyyən etməyə imkan verən geri sayım taymerindən istifadə edir. Beləliklə, paketdə xalis TCPKeepAlive standart olaraq 15 saniyəyə təyin edilmişdir:

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

Göndərən tərəf hər dəfə paket ötürüldükdə (həm birinci, həm də ikinci dəfə) taymeri işə salmalı, taymerdən gələn fasilələri idarə etməli və onu dayandırmalıdır.

Beləliklə, biz etibarlı məlumat ötürmə protokollarının əsas anlayışları ilə tanış olduq:

  • yoxlama məbləğləri;
  • bağlamaların ardıcıl nömrələri;
  • taymerlər;
  • müsbət və mənfi qəbzlər.

Ancaq bu, hamısı deyil!

Boru kəməri ilə etibarlı məlumat ötürmə protokolu

Artıq nəzərdən keçirdiyimiz variantda etibarlı çatdırılma protokolu çox səmərəsizdir. RTT artdıqca rabitə kanalı tərəfindən təmin edilən ötürülməni "yavaşlamağa" başlayır. Onun səmərəliliyini artırmaq və rabitə kanalının tutumundan daha yaxşı istifadə etmək üçün boru kəmərindən istifadə olunur.

Etibarlı məlumat ötürülməsinin əsasları

Boru kəmərinin istifadəsi aşağıdakılara səbəb olur:

  • ardıcıllıq nömrələrinin diapazonunun artırılması, çünki bütün göndərilən paketlər (yenidən ötürülmələr istisna olmaqla) unikal şəkildə müəyyən edilməlidir;
  • ötürən və qəbul edən tərəflərdə tamponların artırılması ehtiyacı.

Ardıcıllıq nömrəsi diapazonu və bufer ölçüsü tələbləri protokolun paketin pozulması, itkisi və gecikməsinə cavab olaraq gördüyü tədbirlərdən asılıdır. Boru kəməri vəziyyətində səhvləri düzəltmək üçün iki üsul var:

  • N paketi geri qaytarın;
  • seçmə təkrar.

N paketə qayıtmaq - sürüşmə pəncərə protokolu

Etibarlı məlumat ötürülməsinin əsasları

Göndərən üç növ hadisəni dəstəkləməlidir:

  • daha yüksək səviyyəli protokolla zəng edin. Məlumat göndərmə funksiyası "yuxarıdan" adlandırıldıqda, göndərən tərəf əvvəlcə pəncərənin doldurulma dərəcəsini yoxlayır (yəni qəbzlərin alınmasını gözləyən N göndərilmiş mesajın olması). Pəncərə boşdursa, yeni paket yaradılır və ötürülür və dəyişən dəyərlər yenilənir. Əks halda, göndərən tərəf məlumatları yuxarı təbəqəyə qaytarır və bu, pəncərənin dolu olduğunun gizli göstəricisidir. Tipik olaraq, yuxarı təbəqə bir müddət sonra məlumatları yenidən ötürməyə çalışacaq. Həqiqi tətbiqdə, göndərici, ehtimal ki, məlumatları ya tamponlayacaq (dərhal göndərmək əvəzinə) və ya yuxarı təbəqəyə göndərmə funksiyasını yalnız pəncərə boş olduqda çağırmağa imkan verən sinxronizasiya mexanizminə (məsələn, semafor və ya bayraq) malik olacaq. .
  • təsdiqin alınması. Protokolda sıra nömrəsi N olan paket üçün N-dən əvvəl ardıcıllıq nömrələri olan bütün paketlərin uğurla qəbul edildiyini bildirən ümumi bildiriş verilir.
  • gözləmə intervalı başa çatıb. Paketlərin və qəbzlərin itkiləri və gecikmələri faktlarını müəyyən etmək üçün protokol taymerdən istifadə edir. Taymout intervalı başa çatarsa, göndərən tərəf bütün göndərilən qəbul edilməmiş paketləri yenidən göndərir.

Seçmə təkrar

Pəncərə ölçüsü və ötürmə qabiliyyətinin yayılması gecikmə məhsulu böyük olduqda, boru kəmərində çoxlu sayda paket ola bilər. Belə olan halda, tək paket xətası çoxlu sayda paketin təkrar ötürülməsinə səbəb ola bilər, onların əksəriyyəti tələb olunmur.

Misal

Üst nəzəri praktiki həyata keçirilməsində təcrübələr toplanır TCP. Və kimsə necə yaxşı bilirsə - xoş.

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

Müştəri

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

Buraxılış

Etibarlı məlumat ötürülməsini və istifadəsini təmin edən mexanizmlər

Mexanizm
Ərizə, şərh

Yoxlama məbləği
Köçürülən paketdə bit xətalarını aşkar etmək üçün istifadə olunur

Timer
Taymout intervalını geri sayır və onun nə vaxt bitdiyini göstərir. Sonuncu o deməkdir ki, ötürmə zamanı paketin və ya onun qəbzinin itirilməsi ehtimalı yüksəkdir. Paket gecikmə ilə çatdırılırsa, lakin itmirsə (taym-aut intervalının vaxtından əvvəl başa çatması) və ya qəbz itirilirsə, təkrar ötürmə qəbul edən tərəfdə dublikat paketə səbəb olur.

Seriya nömrəsi
Göndərəndən alıcıya ötürülən məlumat paketlərinin ardıcıl nömrələnməsi üçün istifadə olunur. Qəbul edilən paketlərin ardıcıl nömrələrindəki boşluqlar alıcıya paket itkisini aşkar etməyə imkan verir. Eyni paket ardıcıllıq nömrələri paketlərin bir-birinin dublikatları olduğunu bildirir

Təsdiq
Qəbul edən tərəf tərəfindən yaradılır və göndərən tərəfə müvafiq paketin və ya paketlər qrupunun uğurla qəbul edildiyini göstərir. Bir qayda olaraq, təsdiq uğurla qəbul edilmiş paketlərin ardıcıl nömrələrini ehtiva edir. Protokoldan asılı olaraq fərdi və qrup təsdiqləmələri fərqləndirilir

Mənfi təsdiq
Alıcı tərəfindən paketin səhv qəbul edildiyi barədə göndərənə məlumat vermək üçün istifadə olunur. Mənfi təsdiq adətən düzgün qəbul edilməmiş paketin sıra nömrəsini ehtiva edir

Pəncərə, konveyerləşdirmə
Paketləri ötürmək üçün istifadə edilə bilən ardıcıl nömrələr diapazonunu məhdudlaşdırın. Multicast və handshake protokolun ötürmə qabiliyyətini təşəkkürləri gözləməkdən əhəmiyyətli dərəcədə artıra bilər. Görəcəyimiz kimi, pəncərənin ölçüsü qəbuledici tərəfin qəbulu və tamponlama imkanlarına, həmçinin şəbəkənin yüklənmə səviyyəsinə əsasən hesablana bilər.

Şəbəkə üçün Go istifadəsinin daha çox nümunələri

В depolar.

Mənbə: www.habr.com

Добавить комментарий