Die Grundlagen einer zuverlässigen Datenübertragung

CPAP


Diejenigen, die die Netzwerke und Protokolle verstehen wollen, sind engagiert.


Kurz

, Go, UDP TCP. , , " . ", .


Transportschichtprotokoll


Bietet eine logische Verbindung zwischen Anwendungsprozessen, die auf verschiedenen Hosts ausgeführt werden. Eine logische Verbindung aus Sicht von Anwendungen sieht aus wie ein Kanal, der Prozesse direkt verbindet.



, ( — DPI). , , , .



( ) .



, () . . , -.





. , .


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


— , , , , , .



:


  • ;
  • ;
  • .

, , (Automatic Repeat reQuest, ARQ).
, , .
, TCP, , .



,


, , .
:


  • ;
  • .

, , , , . : . , . net TCPKeepAlive 15 :


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

( , ), .


, :


  • ;
  • ;
  • ;
  • .

!



, , . «» , , RTT. , .



:


  • , ( ) ;
  • .

, , . :


  • N ;
  • .

N —



:


  • . «» , ( N , ). , , . , , . . , , ( ), (, ), .
  • . N , , , N, .
  • . . , .


, . , .



TCP. - , — welcome.


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


,


,
. , . , , ( ), ,
. . ,
, . .
, . ,
,Begrenzen Sie den Bereich der Sequenznummern, die zum Übertragen von Paketen verwendet werden können. Multicast und Handshake können den Protokolldurchsatz im Vergleich zum Bestätigungs-Standby-Modus erheblich erhöhen. Wie wir sehen werden, kann die Fenstergröße auf der Grundlage der Empfangs- und Pufferfähigkeiten der Empfangsseite sowie des Netzwerklastniveaus berechnet werden

Weitere Beispiele für die Verwendung von Go für die Vernetzung


Im Repository .


All Articles