MCPcopy Index your code
hub / github.com/cevatbarisyilmaz/lossy

github.com/cevatbarisyilmaz/lossy @v0.2.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.2.1 ↗ · + Follow
19 symbols 76 edges 5 files 2 documented · 11% updated 6y agov0.2.1 · 2019-10-05★ 3202 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

lossy

GoDoc GitHub release (latest SemVer) GitHub Go Report Card

Go package to simulate bandwidth, latency and packet loss for net.PacketConn and net.Conn interfaces.

Its main usage is to test robustness of applications and network protocols run over unreliable transport protocols such as UDP or IP. As a side benefit, it can also be used as outbound bandwidth limiter.

lossy only alters the writing side of the connection, reading side is kept as it is.

Example

package main

import (
    "fmt"
    "github.com/cevatbarisyilmaz/lossy"
    "log"
    "math/rand"
    "net"
    "time"
)

const packetSize = 64

func main() {
    // Create two connection endpoints over UDP
    packetConn, conn := createConnections()

    // Create a lossy packet connection
    bandwidth := 1048 // 8 Kbit/s
    minLatency := 100 * time.Millisecond
    maxLatency := time.Second
    packetLossRate := 0.33
    headerOverhead := lossy.UDPv4MinHeaderOverhead
    lossyPacketConn := lossy.NewPacketConn(packetConn, bandwidth, minLatency, maxLatency, packetLossRate, headerOverhead)

    // Write some packets via lossy
    var bytesWritten int
    const packetCount = 32
    go func() {
        for i := 0; i < packetCount; i++ {
            packet := createPacket()
            _, err := lossyPacketConn.WriteTo(packet, conn.LocalAddr())
            if err != nil {
                log.Fatal(err)
            }
            bytesWritten += len(packet) + headerOverhead
        }
        fmt.Println("Sent", packetCount, "packets with total size of", bytesWritten, "bytes")
        baseTransmissionDuration := time.Duration(float64(bytesWritten * int(time.Second)) / float64(bandwidth))
        earliestCompletion := baseTransmissionDuration + minLatency
        latestCompletion := baseTransmissionDuration + maxLatency
        fmt.Println("Expected transmission duration is between", earliestCompletion, "and", latestCompletion)
    }()

    // Read packets at the other side
    const timeout = 3 * time.Second
    var packets, bytesRead int
    startTime := time.Now()
    for {
        _ = conn.SetReadDeadline(time.Now().Add(timeout))
        buffer := make([]byte, packetSize)
        n, err := conn.Read(buffer)
        if err != nil {
            break
        }
        bytesRead += n + headerOverhead
        packets++
    }
    dur := time.Now().Sub(startTime) - timeout
    fmt.Println("Received", packets, "packets with total size of", bytesRead, "bytes in", dur)

    // Close the connections
    _ = lossyPacketConn.Close()
    _ = conn.Close()
}

func createConnections() (net.PacketConn, net.Conn) {
    packetConn, err := net.ListenUDP("udp", &net.UDPAddr{
        IP:   net.IPv4(127, 0, 0, 1),
        Port: 0,
    })
    if err != nil {
        log.Fatal(err)
    }
    conn, err := net.DialUDP("udp", nil, packetConn.LocalAddr().(*net.UDPAddr))
    if err != nil {
        log.Fatal(err)
    }
    return packetConn, conn
}

func createPacket() []byte {
    packet := make([]byte, packetSize)
    rand.Read(packet)
    return packet
}

Output

Sent 32 packets with total size of 2944 bytes
Expected transmission duration is between 2.909160305s and 3.809160305s
Received 23 packets with total size of 2116 bytes in 3.2507523s

Core symbols most depended-on inside this repo

Shape

Function 9
Method 8
Struct 2

Languages

Go100%

Modules by API surface

packet_conn.go6 symbols
lossy_test.go6 symbols
conn.go6 symbols
example_test.go1 symbols

For agents

$ claude mcp add lossy \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page