lossy

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

Github星跟蹤圖

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

主要指標

概覽
名稱與所有者cevatbarisyilmaz/lossy
主編程語言Go
編程語言Go (語言數: 1)
平台
許可證MIT License
所有者活动
創建於2019-08-21 13:46:06
推送於2019-10-05 12:22:12
最后一次提交2019-08-25 16:20:34
發布數4
最新版本名稱v0.2.1 (發布於 )
第一版名稱v0.1.0 (發布於 )
用户参与
星數322
關注者數4
派生數9
提交數14
已啟用問題?
問題數3
打開的問題數2
拉請求數0
打開的拉請求數0
關閉的拉請求數0
项目设置
已啟用Wiki?
已存檔?
是復刻?
已鎖定?
是鏡像?
是私有?