Etibarlı məlumat ötürmə əsasları

Etibarlı məlumat ötürmə əsasları

Bütün bunlar şəbəkələr və protokollarla maraqlananlara həsr olunur.

Qısa

Məqalədə məlumatın etibarlı ötürülməsinin əsasları müzakirə olunur, o cümlədən Go, UDP və TCP üzrə nümunələr təqdim olunur. Mündəricat bir, iki, três və "Kompyuter Şəbəkələri. En tərtib" kitabından, çünki hamı yalnız Tanenbaum və Olifer haqqında danışır.

Nəqliyyat protokolu

Müxtəlif ev sahibində işləyən tətbiqi proseslər arasında məntiqi əlaqə təmin edir. Tətbiqlər baxımından məntiqi əlaqə, prosesi birbaşa birləşdirən kanal olaraq görünür.

Etibarlı məlumat ötürmə əsasları

Nəqliyyat protokolları son sistemlər tərəfindən dəstəklənir, lakin şəbəkə yönlendiriciləri tərəfindən (istisna ilə — DPI). Göndərən tərəfdə, nəqliyyat səviyyəsi tətbiqi səviyyədən aldığı məlumatları, göndərən tətbiqi prosesdən gələn paketlərə çevirmək üçün istifadə olunur.

Etibarlı məlumat ötürmə əsasları

Bu, tətbiqi səviyyə mesajlarının fraksiyalara bölünməsi (lazım olduqda) və hər birinə nəqliyyat səviyyəsi başlığı əlavə etməklə həyata keçirilir.

Etibarlı məlumat ötürmə əsasları

Daha sonra, nəqliyyat səviyyəsi segmenti göndərənin şəbəkə səviyyəsinə ötürür, burada segment, şəbəkə səviyyəsi paketi (datagram) içində kapsülləşdirilir və göndərilir. Qəbul edən tərəfdə, şəbəkə səviyyəsi, datagramdan nəqliyyat səviyyəsi segmentini çıxarıb onu yuxarı nəqliyyat səviyyəsinə ötürür. Sonra, nəqliyyat səviyyəsi alınan segmenti emal edərək onun məlumatlarını qəbul edən tətbiqə təqdim edir.

Etibarlı məlumat ötürmə əsasları

Məlumatın etibarlı ötürülməsi prinsipləri

Tam etibarlı kanaldan etibarlı məlumatların ötürülməsi

Ən sadə hal. Göndərən tərəf, yuxarı səviyyədən məlumatları qəbul edir, onları özündə saxlayan paketi yaradır və kanala göndərir.

Server

package main

import (
    "log"
    "net"
)

func main() {
    // Serverin IP ünvanı və portu
    serverAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:12000")
    if err != nil {
        log.Fatal(err)
    }

    // portu olan soket yaradırıq
    serverConn, err := net.ListenUDP("udp", serverAddr)
    if err != nil {
        log.Fatal(err)
    }
    // əlaqəni bağlamaq üçün gözləmə
    defer serverConn.Close()

    // məlumatlar üçün tampon yaradırıq
    buf := make([]byte, 1024)

    // bağlantını gözləyirik
    for {
        // sorğunu oxuyuruq
        n, addr, err := serverConn.ReadFromUDP(buf)
        // məlumatları YUXARI səviyyəyə ötürürük: bizdə stdout-a
        println(string(buf[0:n]), " form ", addr.IP.String())
        if err != nil {
            log.Fatal(err)
        }
        // cavab yoxdur, çünki bu UDP + etibarlı kanal
    }
}

Müştəri

package main

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

func main() {
    // Server IP address and port
    serverAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:12000")
    if err != nil {
        log.Fatal(err)
    }
    // Local IP address and port
    localAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0")
    if err != nil {
        log.Fatal(err)
    }
    // Establishing connection
    conn, err := net.DialUDP("udp", localAddr, serverAddr)
    if err != nil {
        log.Fatal(err)
    }
    // Deferred connection close
    defer conn.Close()

    for {
        // Receiving data from the upper layer
        fmt.Print("Köhnə cümlə daxil edin > ")
        var msg string
        _, err := fmt.Scanf("%s", &msg)
        if err != nil {
            log.Fatal(err)
        }
        // A stream of bytes is transmitted, not a string
        buf := []byte(msg)
        // Writing (transmitting) to the connection
        _, err = conn.Write(buf)
        if err != nil {
            log.Fatal(err)
        }
        // One second wait
        time.Sleep(time.Second * 1)
    }
}

Etibarlı məlumat ötürülməsi mümkün olan xətalarla kanaldan

Növbəti mərhələdə, ötürülən bütün paketlərin göndərildiyi sırada alınacağı fikri qəbul edilir, lakin içindəki bitlər zədələnə bilər, çünki kanal bəzən məlumatları yüksək şəkildə ötürülə bilər.

Etibarlı məlumat ötürmə əsasları

Belə olan halda, aşağıdakı mexanizmlər tətbiq olunur:

  • xətanın aşkarlanması;
  • geri bildirim;
  • təkrar ötürmə.

Belə mexanizmlərə malik etibarlı məlumat ötürmə protokolları, avtomatik təkrar sorğu protokolları (Automatic Repeat reQuest, ARQ) adlanır.
Həmçinin, qəbul edən tərəfin son paket ötürməsinin nəticələri barədə heç bir məlumat almadığı halında, təsdiqlərdə də xətaların baş verməsini nəzərə almaq lazımdır.
Bu məsələnin həlli, o cümlədən TCP-də, paket məlumatlarına yeni bir sahənin əlavə olunmasından ibarətdir ki, bu da paketlərin sıralama nömrəsini ehtiva edir.

Etibarlı məlumat ötürmə əsasları

Zədələnmə və paket itkisinin baş verməsini qəbul edən etibarlı məlumat ötürülməsi üçün

Təəssüf ki, zədələnmə ilə yanaşı, şəbəkədə paket itkisi də mövcuddur.
Və bu məsələnin həlli üçün aşağıdakı mexanizmlərin olması tələb olunur:

  • paket itkisinin aşkar edilməsi;
  • itirilmiş paketlərin qəbul edən tərəfə yenidən ötürülməsi.

Həmçinin, paket itkisi ilə yanaşı, təsdiqlərin itirilməsi və ya heç bir şey itirilmədiyində, onun keçirilməsində əhəmiyyətli gecikmə olması ehtimalını nəzərə almaq lazımdır. Hər vəziyyətdə eyni şey edilir: paketin yenidən ötürülməsi. Bu mexanizmin müddətini kontrol etmək üçün gözləmə intervalının bitməsini müəyyən etməyə imkan verən sayğac zamanı istifadə olunur. Belə ki, paket net TCPKeepAlive parametri, standart olaraq 15 saniyə olaraq təyin olunub:

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

Göstərən tərəf hər dəfə paket ötürdükdə (ilk və təkrar daxil olmaqla) sayğacı işə salmalı, sayğacdan kəsilmələri ələ almalı və onu dayandırmalıdır.

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

  • nəzarət cəmi;
  • paketlərin ardıcıl nömrələri;
  • zamanlayıcılar;
  • müsbət və mənfi təsdiqlər.

Amma bu, hələ hamısı deyil!

Verilənlərin etibarlı ötürülməsi protokolu ilə boru kəmərləşmə

Artıq müzakirə etdiyimiz variantda, etibarlı çatdırılma protokolu çox effektiv deyil. O, RTT artdıqca məlumatların ötürülməsi üçün təchiz edilmiş kanalda «dayanmağa» başlayır. Onun effektivliyini artırmaq, kanalın tutumunun daha yaxşı istifadəsi üçün boru kəmərləşmə tətbiq olunur.

Etibarlı məlumat ötürmə əsasları

Boru kəmərləşmənin tətbiqi aşağıdakı nəticələri gətirir:

  • ardıcıl nömrələrin diapazonunun genişlənməsi, çünki bütün göndərilən paketlər (təkrarlanan ötürmələr istisna olmaqla) unikal şəkildə tanınmalıdır;
  • göndərən və qəbul edən tərəflərdə tamponların artırılması ehtiyacı.

Ardıcıl nömrələrin diapazonu və tampon ölçüləri ilə bağlı tələblər, protokolun paketlərin pozulmasına, itirilməsinə və gecikməsinə cavab olaraq apardığı fəaliyyətlərdən asılıdır. Boru kəmərləşmə vəziyyətində iki səhv düzəltmə metodu mövcuddur:

  • N paketi geri qaytarılması;
  • seçici təkrar.

N paketi geri qaytarılması - sürüşən pəncərə protokolu

Etibarlı məlumat ötürmə əsasları

Göndərən üç növ hadisəni saxlamalıdır:

  • yuxarı səviyyə protokolu ilə çağırış. Yuxarıdan data göndərmə funksiyası çağı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 təsdiq gözləyən N göndərilmiş mesajın olub olmadığını). Əgər pəncəre boşdursa, yeni paket formalaşır və göndərilir, bununla yanaşı dəyişənlərin dəyərləri yenilənir. Əks halda, göndərən tərəf məlumatları yuxarı səviyyəyə qaytarır və bu, pəncərenin doldurulduğuna dair qeyri-müəyyən bir göstərişdir. Adətən, yuxarı səviyyə müəyyən bir müddətdən sonra məlumatların təkrar göndərilməsi üçün cəhdlər edir. Gerçək tətbiqdə göndərən, çox güman ki, ya məlumatları tamponlaşdırır (tez bir zamanda göndərmək əvəzinə), ya da yuxarı səviyyənin yalnız boş pəncərə olduqda göndərmə funksiyasını çağırmasına imkan verən bir sinxronizasiya mexanizminə (məsələn, semaphore və ya bayraq) malik olardı.
  • təsdiq alınması. Protokolda N ardıcıl nömrəli paket üçün, N-dən əvvəlki bütün ardıcıl nömrələrə müvəffəqiyyətlə qəbul edildiyini göstərən ümumi təsdiq verilir.
  • gözləmə müddətinin bitməsi. Paketlərin və təsdiqlərin itirilməsi və gecikmələri faktlarını müəyyənləşdirmək üçün protokol zamanlayıcı istifadə edir. Əgər gözləmə müddəti başa çatırsa, göndərən tərəf bütün göndərilmiş təsdiq olunmamış paketləri yenidən göndərir.

seçici təkrar

Pəncərə ölçüsü və gecikmə zamanı bant genişliyi böyük olduqda, boru kəmərində çox sayda paket ola bilər. Bu halda, bir paketin xətası, lazım olmayan çox sayda paketin yenidən göndərilməsinə səbəb ola bilər.

Məsələn

Ən yaxşı teorik təcrübələr praktiki icra ilə toplanmışdır TCP. Və kiminsə daha yaxşı bildiyi halda - xoş gəlmisiniz.

Server

package main

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

func main() {
    // bağlantı portu ilə soket yaradır
    ln, err := net.Listen("tcp", ":8081")
    if err != nil {
        log.Fatalln(err)
    }
    // zəng gözləyir
    conn, _ := ln.Accept()

    for {
        // məlumatları oxuyur
        msg, err := bufio.NewReader(conn).ReadString('n')
        if err != nil {
            log.Fatalln(err)
        }
        // mesajı stdout-a çıxarır
        fmt.Print("Göndərilən Mesaj:", string(msg))
        // sətiri böyük hərflə yazır
        newMsg := strings.ToUpper(msg)
        // məlumatı göndərir
        conn.Write([]byte(newMsg + "n"))
    }
}

Müştəri

package main

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

func main() {
    // bağlantı qurur
    conn, err := net.Dial("tcp", "127.0.0.1:8081")
    if err != nil {
        log.Fatalln(err)
    }

    for {
        // stdin-dən məlumatları oxuyur
        reader := bufio.NewReader(os.Stdin)
        fmt.Print("Göndəriləcək mətn: ")
        // sətir-sətir
        text, err := reader.ReadString('n')
        if err != nil {
            log.Fatalln(err)
        }
        // göndərir
        fmt.Fprintf(conn, text+"n")
        // qəbul edir
        msg, err := bufio.NewReader(conn).ReadString('n')
        if err != nil {
            log.Fatalln(err)
        }
        // alınan cavabı çıxarır
        fmt.Print("Serverdən Mesaj: " + msg)
    }
}

Çıktı

Məlumatların etibarlı ötürülməsini təmin edən mexanizm və onların istifadəsi

Mexanizm
Tətbiq, şərh

Kontrol cəmi
Göndərilmiş paketdə bit həta aşkar etmək üçün istifadə olunur

Taymer
Gözləmə müddətinin sayımı və onun bitməsinin göstəricisi. Bu, paket və ya onun təsdiqi ötürülmə zamanı yüksək ehtimalla itirilib deməkdir. Paket gecikmə ilə çatdırılsa da, itirilmiş təsdiq halında, yenidən göndərmə qəbul edən tərəfdə paketlərin çoxalmasına səbəb olur.

Sıra nömrəsi
Göndərən tərəfdən qəbul edəyənə ötürülən məlumat paketlərinin sıra nömrəsini təmin etmək üçün istifadə olunur. Qəbul edilən paketlərdəki sıralama nömrələrindəki boşluqlar, qəbul edənin paket itkisinin olduğunu aşkar etməyə imkan tanıyır. Eyni sıra nömrələrinə malik paketlər, paketlərin bir-birini təkrarladığını göstərir.

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 paketlərin və ya paket qruplarının uğurla qəbul edildiyini bildirir. Adətən, təsdiq uğurla qəbul edilən paketlərin sıra nömrələrini ehtiva edir. Protokoldan asılı olaraq fərdi və qruplaşdırılmış təsdiqlər arasında fərq var.

Müsbət təsdiq
Alıcının göndericiye paketin hatalı alındığını bildirmek için kullandığı bir yöntemdir. Olumsuz onay genellikle hatalı alınan paketin sıralı numarasını içerir.

Pencere, boru hattı
Paket aktarımı için kullanılabilecek sıralı numaraların aralığını sınırlayan unsurlardır. Gruplu aktarım ve el sıkışma, onay bekleme moduna göre protokollerin bant genişliğini önemli ölçüde artırabilir. Gördüğümüz gibi, pencere boyutu, alıcı tarafın kabul etme ve tamponlama yetenekleri ile ağın yükleme seviyesine dayanarak hesaplanabilir.

Ağ ile çalışmak için Go'nun diğer kullanım örnekleri

İ deposunda.

Mənbə: habr.com

DDoS qoruması olan saytlara etibarlı hosting satın alın, VPS VDS serverlər 🔥 DDoS qoruması olan saytlara etibarlı hosting satın alın, VPS VDS serverlər | ProHoster