Les bases d'un transfert de données fiable

CPAP


Ceux qui cherchent à comprendre les réseaux et protocoles sont dédiés.


Brièvement

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


Protocole de couche transport


Fournit une connexion logique entre les processus d'application s'exécutant sur différents hôtes. Une connexion logique du point de vue des applications ressemble à un canal qui connecte directement les processus.



, ( — 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)
    }
}


,


,
. , . , , ( ), ,
. . ,
, . .
, . ,
,Limitez la plage de numéros de séquence pouvant être utilisés pour transmettre des paquets. La multidiffusion et la négociation peuvent augmenter considérablement le débit du protocole par rapport au mode d'attente d'accusé de réception. Comme nous le verrons, la taille de la fenêtre peut être calculée sur la base des capacités de réception et de mise en mémoire tampon du côté récepteur, ainsi que du niveau de charge du réseau

Autres exemples d'utilisation de Go pour la mise en réseau


Dans le référentiel .


All Articles