From b79bb082abca3703d8dbcfebfc1049d04b1ba1f7 Mon Sep 17 00:00:00 2001
From: nnbcccscdscdsc <2709767634@qq.com>
Date: Tue, 24 Mar 2026 13:35:40 +0800
Subject: [PATCH 1/2] =?UTF-8?q?fix:=E8=AE=BE=E7=BD=AE=E7=BC=93=E5=86=B2?=
=?UTF-8?q?=E5=8C=BAbuffer=EF=BC=8C=E8=AE=BE=E7=BD=AE=E8=B6=B3=E5=A4=9F?=
=?UTF-8?q?=E5=A4=A7=E7=9A=84=20oob=20buffer=20=E6=9D=A5=E6=8E=A5=E6=94=B6?=
=?UTF-8?q?=E6=8E=A7=E5=88=B6=E6=B6=88=E6=81=AF=EF=BC=8C=E8=B0=83=E7=94=A8?=
=?UTF-8?q?=20recvmsg=20=E4=BB=8E=20errqueue=20=E8=AF=BB=E4=B8=80=E6=9D=A1?=
=?UTF-8?q?=E6=B6=88=E6=81=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
cmd/internal/transport/tcp_linux.go | 21 ++++++++++++++++++++-
cmd/internal/transport/tcp_linux_test.go | 2 +-
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/cmd/internal/transport/tcp_linux.go b/cmd/internal/transport/tcp_linux.go
index e753791..6578bf1 100644
--- a/cmd/internal/transport/tcp_linux.go
+++ b/cmd/internal/transport/tcp_linux.go
@@ -15,7 +15,8 @@ import (
)
const (
- linuxTimestampControlBufferSize = 256 // 控制消息缓冲区。
+ linuxTimestampControlBufferSize = 2560 // 控制消息缓冲区。
+ linuxSocketWriteBufferSize = 10 * 1024 * 1024 // 请求把 socket 发送缓冲区调到 10 MiB。
linuxTXTimestampWaitTimeout = 250 * time.Millisecond // 等待 TX 时间戳的上限。
linuxTXTimestampPollInterval = time.Millisecond // 轮询 errqueue 的间隔。
linuxDataPollInterval = time.Millisecond // 轮询普通收发的间隔。
@@ -88,6 +89,10 @@ func (c *TCPConn) initLinuxTimestamping() error {
return fmt.Errorf("transport: missing syscall conn")
}
+ if err := configureLinuxSocketWriteBuffer(rawConn); err != nil {
+ return fmt.Errorf("transport: configure socket write buffer: %w", err)
+ }
+
//socket是否可以成功打开 timestamping 取决于内核版本和配置,尝试多个 flag 组合直到成功或遇到非 EINVAL 错误。
if err := enableLinuxTimestamping(rawConn); err != nil {
return fmt.Errorf("transport: enable linux timestamping: %w", err)
@@ -97,6 +102,20 @@ func (c *TCPConn) initLinuxTimestamping() error {
return nil
}
+// 设置 TCP缓冲区buffer size
+func configureLinuxSocketWriteBuffer(rawConn syscall.RawConn) error {
+ var lastErr error
+
+ err := rawConn.Control(func(fd uintptr) {
+ lastErr = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_SNDBUF, linuxSocketWriteBufferSize)
+ })
+ if err != nil {
+ return err
+ }
+
+ return lastErr
+}
+
// 给 socket开权限打开TX software timestamping。
func enableLinuxTimestamping(rawConn syscall.RawConn) error {
flagCandidates := []int{ //不同linux版本可能支持不同的 flag 组合,尝试多个组合直到成功。
diff --git a/cmd/internal/transport/tcp_linux_test.go b/cmd/internal/transport/tcp_linux_test.go
index ac1e46e..114f685 100644
--- a/cmd/internal/transport/tcp_linux_test.go
+++ b/cmd/internal/transport/tcp_linux_test.go
@@ -182,7 +182,7 @@ func TestSelectTXTimestampEventsFallsBackToHighestObservedID(t *testing.T) {
func TestLinuxTimestampingDebugLoggerCapturesChunkAndErrqueueEvents(t *testing.T) {
clientConn, serverConn := newTCPPair(t)
- setTCPWriteBuffer(t, clientConn, 4096)
+ setTCPWriteBuffer(t, clientConn, 10*1024*1024)
debugLogger := &recordingTXTimestampDebugLogger{}
senderLogger := &recordingLogger{}
From 1cb964c30b3055d4b041dce03add0587ae2a4e74 Mon Sep 17 00:00:00 2001
From: nnbcccscdscdsc <2709767634@qq.com>
Date: Tue, 24 Mar 2026 15:38:21 +0800
Subject: [PATCH 2/2] =?UTF-8?q?fix=EF=BC=9A=E6=9B=B4=E6=96=B0=E6=97=A5?=
=?UTF-8?q?=E5=BF=97=E7=BB=9F=E8=AE=A1=E6=95=B0=E6=8D=AE&=E5=A2=9E?=
=?UTF-8?q?=E5=8A=A0=E6=B6=88=E6=81=AF=E7=BC=93=E5=86=B2=E5=8C=BA=E7=9A=84?=
=?UTF-8?q?=E6=97=B6=E9=97=B4=E6=88=B3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.gitignore | 3 +-
cmd/internal/latencylog/summary.go | 33 ++++++++---
cmd/internal/latencylog/summary_chart.go | 52 ++++++++++++++++++
cmd/internal/latencylog/summary_chart_test.go | 31 +++++++----
cmd/internal/latencylog/summary_test.go | 45 ++++++++++-----
cmd/internal/transport/tcp_linux.go | 10 ++--
latencysummary | Bin 5642380 -> 0 bytes
7 files changed, 136 insertions(+), 38 deletions(-)
delete mode 100755 latencysummary
diff --git a/.gitignore b/.gitignore
index 1b82a02..70b22f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
bin/*
inbox/*
-*.jsonl
\ No newline at end of file
+*.jsonl
+*.html
diff --git a/cmd/internal/latencylog/summary.go b/cmd/internal/latencylog/summary.go
index 7d6429a..89a1bba 100644
--- a/cmd/internal/latencylog/summary.go
+++ b/cmd/internal/latencylog/summary.go
@@ -31,14 +31,17 @@ type Summary struct {
BodySize int `json:"body_size"` //消息体大小(字节数)
Timestamps map[string]int64 `json:"timestamps"` //事件时间戳,key 是事件名称,value 是 UnixNano 时间戳
- AProcessingLatencyNS *int64 `json:"a_processing_latency_ns,omitempty"` // A 处理时延:A_TX_SCHED - A_APP_PREP_BEGIN
- AQueueLatencyNS *int64 `json:"a_queue_latency_ns,omitempty"` // A 排队时延:A_TX_SOFTWARE - A_TX_SCHED
- ABTransportPropagationNS *int64 `json:"a_b_transport_propagation_ns,omitempty"` // A-B 传输+传播时延近似:B_APP_RECV - A_TX_SOFTWARE
- BKernelReceivePathLatencyNS *int64 `json:"b_kernel_receive_path_latency_ns,omitempty"` // B 内核接收路径近似:B_APP_RECV - B_RX_SOFTWARE
- BProcessingLatencyNS *int64 `json:"b_processing_latency_ns,omitempty"` // B 处理时延:B_PERSIST_END - B_APP_RECV
- EndToEndLatencyNS *int64 `json:"end_to_end_latency_ns,omitempty"` // 端到端时延:B_PERSIST_END - A_APP_PREP_BEGIN
- ApproxRTTNS *int64 `json:"approx_rtt_ns,omitempty"` // 近似 RTT:首条反向应答的 B_APP_RECV - 当前请求的 A_TX_SOFTWARE
- MissingTimestamps []string `json:"missing_timestamps,omitempty"` // 缺失的时间戳列表,包含 requiredTimestampNames 中但在原始事件中没有的事件名称
+ AProcessingLatencyNS *int64 `json:"a_processing_latency_ns,omitempty"` // A 处理时延:A_TX_SCHED - A_APP_PREP_BEGIN
+ AQueueLatencyNS *int64 `json:"a_queue_latency_ns,omitempty"` // A 排队时延:A_TX_SOFTWARE - A_TX_SCHED
+ ABTransportPropagationNS *int64 `json:"a_b_transport_propagation_ns,omitempty"` // A-B 传输+传播时延近似:B_APP_RECV - A_TX_SOFTWARE
+ BKernelReceivePathLatencyNS *int64 `json:"b_kernel_receive_path_latency_ns,omitempty"` // B 内核接收路径近似:B_APP_RECV - B_RX_SOFTWARE
+ BProcessingLatencyNS *int64 `json:"b_processing_latency_ns,omitempty"` // B 处理时延:B_PERSIST_END - B_APP_RECV
+ EndToEndLatencyNS *int64 `json:"end_to_end_latency_ns,omitempty"` // 端到端时延:B_PERSIST_END - A_APP_PREP_BEGIN
+ AProcessingBitrateBPS *float64 `json:"a_processing_bitrate_bps,omitempty"` // A 处理阶段近似比特率:(BodySize * 8) / A 处理时延(秒)
+ ABTransportPropagationBitrateBPS *float64 `json:"a_b_transport_propagation_bitrate_bps,omitempty"` // A-B 传输+传播阶段近似比特率:(BodySize * 8) / A-B 传输+传播时延(秒)
+ EndToEndBitrateBPS *float64 `json:"end_to_end_bitrate_bps,omitempty"` // 端到端近似比特率:(BodySize * 8) / 端到端时延(秒)
+ ApproxRTTNS *int64 `json:"approx_rtt_ns,omitempty"` // 近似 RTT:首条反向应答的 B_APP_RECV - 当前请求的 A_TX_SOFTWARE
+ MissingTimestamps []string `json:"missing_timestamps,omitempty"` // 缺失的时间戳列表,包含 requiredTimestampNames 中但在原始事件中没有的事件名称
}
// LoadEventsFromFiles 从JSONL 原始日志文件中加载事件。
@@ -213,6 +216,10 @@ func completeSummary(summary *Summary) {
if value := subtractIfPresent(summary.Timestamps, EventBPersistEnd, EventAAppPrepBegin); value != nil {
summary.EndToEndLatencyNS = value
}
+
+ summary.AProcessingBitrateBPS = calculateBitrateBPS(summary.BodySize, summary.AProcessingLatencyNS)
+ summary.ABTransportPropagationBitrateBPS = calculateBitrateBPS(summary.BodySize, summary.ABTransportPropagationNS)
+ summary.EndToEndBitrateBPS = calculateBitrateBPS(summary.BodySize, summary.EndToEndLatencyNS)
}
type routeKey struct {
@@ -340,6 +347,16 @@ func subtractSummaryTimestamps(endSummary *Summary, endName string, beginSummary
return &value
}
+// 除法函数,如果 bodySize <= 0 或 latencyNS 不存在或 <= 0,则返回 nil;否则返回 bodySize / latencyNS 的结果。
+func calculateBitrateBPS(bodySize int, latencyNS *int64) *float64 {
+ if bodySize <= 0 || latencyNS == nil || *latencyNS <= 0 {
+ return nil
+ }
+
+ value := float64(bodySize) * 8 * 1_000_000_000 / float64(*latencyNS)
+ return &value
+}
+
// 判断事件是否是业务相关的时延事件(其中一项)
func IsBusinessEvent(event Event) bool {
switch event.Event {
diff --git a/cmd/internal/latencylog/summary_chart.go b/cmd/internal/latencylog/summary_chart.go
index 30b7559..a37a4c2 100644
--- a/cmd/internal/latencylog/summary_chart.go
+++ b/cmd/internal/latencylog/summary_chart.go
@@ -131,6 +131,23 @@ const summaryChartHTMLTemplate = `
font-size: 13px;
margin-bottom: 12px;
}
+ .ratio-list {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin: -2px 0 12px;
+ }
+ .ratio-pill {
+ display: inline-flex;
+ align-items: center;
+ padding: 6px 10px;
+ border-radius: 999px;
+ border: 1px solid var(--border);
+ background: #f7f9fc;
+ color: var(--text);
+ font-size: 12px;
+ line-height: 1.2;
+ }
.bar {
height: 24px;
display: flex;
@@ -216,6 +233,13 @@ const summaryChartHTMLTemplate = `
{{.Subtitle}}
{{.ApproxRTT}}
+ {{if .RatioMetrics}}
+
+ {{range .RatioMetrics}}
+ {{.Label}} {{.Value}}
+ {{end}}
+
+ {{end}}
{{range .Segments}}
@@ -265,6 +289,7 @@ type summaryChartRow struct {
EndToEnd string
ApproxRTT string
MissingTimestamps string
+ RatioMetrics []summaryChartValue
Segments []summaryChartSegment
}
@@ -275,6 +300,11 @@ type summaryChartSegment struct {
WidthPercent float64
}
+type summaryChartValue struct {
+ Label string
+ Value string
+}
+
type summaryChartSegmentMetric struct {
label string
value *int64
@@ -366,6 +396,24 @@ func buildSummaryChartRow(summary Summary) summaryChartRow {
row.ApproxRTT = fmt.Sprintf("Approx RTT: %s", formatLatencyNS(*summary.ApproxRTTNS))
}
+ ratioMetrics := []struct {
+ label string
+ value *float64
+ }{
+ {label: "A processing bitrate", value: summary.AProcessingBitrateBPS},
+ {label: "A-B transport + propagation bitrate", value: summary.ABTransportPropagationBitrateBPS},
+ {label: "End-to-end bitrate", value: summary.EndToEndBitrateBPS},
+ }
+ for _, metric := range ratioMetrics {
+ if metric.value == nil || *metric.value <= 0 {
+ continue
+ }
+ row.RatioMetrics = append(row.RatioMetrics, summaryChartValue{
+ Label: metric.label,
+ Value: formatBitrateBPS(*metric.value),
+ })
+ }
+
if summary.EndToEndLatencyNS == nil || *summary.EndToEndLatencyNS <= 0 {
return row
}
@@ -444,3 +492,7 @@ func buildSummaryChartSubtitle(summary Summary) string {
func formatLatencyNS(ns int64) string {
return fmt.Sprintf("%.3f ms", float64(ns)/1_000_000)
}
+
+func formatBitrateBPS(bitsPerSecond float64) string {
+ return fmt.Sprintf("%.3f Mb/s", bitsPerSecond/1_000_000)
+}
diff --git a/cmd/internal/latencylog/summary_chart_test.go b/cmd/internal/latencylog/summary_chart_test.go
index be466ac..d9f41ec 100644
--- a/cmd/internal/latencylog/summary_chart_test.go
+++ b/cmd/internal/latencylog/summary_chart_test.go
@@ -15,20 +15,26 @@ func TestWriteSummariesHTMLChart(t *testing.T) {
transport := int64(40_000_000)
bProcessing := int64(30_000_000)
endToEnd := int64(100_000_000)
+ aProcessingBitrate := float64(5) * 8 * 1_000_000_000 / float64(aProcessing)
+ transportBitrate := float64(5) * 8 * 1_000_000_000 / float64(transport)
+ endToEndBitrate := float64(5) * 8 * 1_000_000_000 / float64(endToEnd)
summaries := []Summary{
{
- MessageType: protocol.MessageTypeText,
- MessageID: 7,
- From: "peer-a",
- To: "peer-b",
- BodySize: 5,
- AProcessingLatencyNS: &aProcessing,
- AQueueLatencyNS: &aQueue,
- ABTransportPropagationNS: &transport,
- BProcessingLatencyNS: &bProcessing,
- EndToEndLatencyNS: &endToEnd,
- ApproxRTTNS: &endToEnd,
+ MessageType: protocol.MessageTypeText,
+ MessageID: 7,
+ From: "peer-a",
+ To: "peer-b",
+ BodySize: 5,
+ AProcessingLatencyNS: &aProcessing,
+ AQueueLatencyNS: &aQueue,
+ ABTransportPropagationNS: &transport,
+ BProcessingLatencyNS: &bProcessing,
+ EndToEndLatencyNS: &endToEnd,
+ AProcessingBitrateBPS: &aProcessingBitrate,
+ ABTransportPropagationBitrateBPS: &transportBitrate,
+ EndToEndBitrateBPS: &endToEndBitrate,
+ ApproxRTTNS: &endToEnd,
},
{
MessageType: protocol.MessageTypeFile,
@@ -58,6 +64,9 @@ func TestWriteSummariesHTMLChart(t *testing.T) {
"peer-a -> peer-b | 5 bytes",
"End-to-end: 100.000 ms",
"Approx RTT: 100.000 ms",
+ "A processing bitrate 0.002 Mb/s",
+ "A-B transport + propagation bitrate 0.001 Mb/s",
+ "End-to-end bitrate 0.000 Mb/s",
"A processing 20.000 ms",
"A-B transport + propagation 40.000 ms",
"file #8 (payload.bin)",
diff --git a/cmd/internal/latencylog/summary_test.go b/cmd/internal/latencylog/summary_test.go
index e8ac2f8..cb4bc8b 100644
--- a/cmd/internal/latencylog/summary_test.go
+++ b/cmd/internal/latencylog/summary_test.go
@@ -13,13 +13,13 @@ import (
func TestSummarizeEventsComputesLatencyMetrics(t *testing.T) {
events := []Event{
- {TsUnixNano: 100, Event: EventAAppPrepBegin, MessageType: protocol.MessageTypeText, MessageID: 1, From: "peer-a", To: "peer-b"},
- {TsUnixNano: 120, Event: EventATXSched, MessageType: protocol.MessageTypeText, MessageID: 1, From: "peer-a", To: "peer-b"},
- {TsUnixNano: 140, Event: EventATXSoftware, MessageType: protocol.MessageTypeText, MessageID: 1, From: "peer-a", To: "peer-b"},
- {TsUnixNano: 180, Event: EventBRXSoftware, MessageType: protocol.MessageTypeText, MessageID: 1, From: "peer-a", To: "peer-b"},
- {TsUnixNano: 220, Event: EventBAppRecv, MessageType: protocol.MessageTypeText, MessageID: 1, From: "peer-a", To: "peer-b"},
- {TsUnixNano: 230, Event: EventBPersistBegin, MessageType: protocol.MessageTypeText, MessageID: 1, From: "peer-a", To: "peer-b"},
- {TsUnixNano: 260, Event: EventBPersistEnd, MessageType: protocol.MessageTypeText, MessageID: 1, From: "peer-a", To: "peer-b"},
+ {TsUnixNano: 100, Event: EventAAppPrepBegin, MessageType: protocol.MessageTypeText, MessageID: 1, From: "peer-a", To: "peer-b", BodySize: 320},
+ {TsUnixNano: 120, Event: EventATXSched, MessageType: protocol.MessageTypeText, MessageID: 1, From: "peer-a", To: "peer-b", BodySize: 320},
+ {TsUnixNano: 140, Event: EventATXSoftware, MessageType: protocol.MessageTypeText, MessageID: 1, From: "peer-a", To: "peer-b", BodySize: 320},
+ {TsUnixNano: 180, Event: EventBRXSoftware, MessageType: protocol.MessageTypeText, MessageID: 1, From: "peer-a", To: "peer-b", BodySize: 320},
+ {TsUnixNano: 220, Event: EventBAppRecv, MessageType: protocol.MessageTypeText, MessageID: 1, From: "peer-a", To: "peer-b", BodySize: 320},
+ {TsUnixNano: 230, Event: EventBPersistBegin, MessageType: protocol.MessageTypeText, MessageID: 1, From: "peer-a", To: "peer-b", BodySize: 320},
+ {TsUnixNano: 260, Event: EventBPersistEnd, MessageType: protocol.MessageTypeText, MessageID: 1, From: "peer-a", To: "peer-b", BodySize: 320},
}
summaries := SummarizeEvents(events)
@@ -46,6 +46,15 @@ func TestSummarizeEventsComputesLatencyMetrics(t *testing.T) {
if got := ptrValue(summary.EndToEndLatencyNS); got != 160 {
t.Fatalf("EndToEndLatencyNS = %d, want 160", got)
}
+ if got := ptrValueFloat(summary.AProcessingBitrateBPS); got != 128_000_000_000 {
+ t.Fatalf("AProcessingBitrateBPS = %v, want 128000000000", got)
+ }
+ if got := ptrValueFloat(summary.ABTransportPropagationBitrateBPS); got != 32_000_000_000 {
+ t.Fatalf("ABTransportPropagationBitrateBPS = %v, want 32000000000", got)
+ }
+ if got := ptrValueFloat(summary.EndToEndBitrateBPS); got != 16_000_000_000 {
+ t.Fatalf("EndToEndBitrateBPS = %v, want 16000000000", got)
+ }
if got := summary.Timestamps[EventBRXSoftware]; got != 180 {
t.Fatalf("timestamps[%q] = %d, want 180", EventBRXSoftware, got)
}
@@ -128,12 +137,12 @@ func TestLoadAndWriteSummaryFiles(t *testing.T) {
})
for _, event := range []Event{
- {TsUnixNano: 100, Event: EventAAppPrepBegin, MessageType: protocol.MessageTypeText, MessageID: 3, From: "peer-a", To: "peer-b"},
- {TsUnixNano: 120, Event: EventATXSched, MessageType: protocol.MessageTypeText, MessageID: 3, From: "peer-a", To: "peer-b"},
- {TsUnixNano: 140, Event: EventATXSoftware, MessageType: protocol.MessageTypeText, MessageID: 3, From: "peer-a", To: "peer-b"},
- {TsUnixNano: 180, Event: EventBRXSoftware, MessageType: protocol.MessageTypeText, MessageID: 3, From: "peer-a", To: "peer-b"},
- {TsUnixNano: 220, Event: EventBAppRecv, MessageType: protocol.MessageTypeText, MessageID: 3, From: "peer-a", To: "peer-b"},
- {TsUnixNano: 260, Event: EventBPersistEnd, MessageType: protocol.MessageTypeText, MessageID: 3, From: "peer-a", To: "peer-b"},
+ {TsUnixNano: 100, Event: EventAAppPrepBegin, MessageType: protocol.MessageTypeText, MessageID: 3, From: "peer-a", To: "peer-b", BodySize: 320},
+ {TsUnixNano: 120, Event: EventATXSched, MessageType: protocol.MessageTypeText, MessageID: 3, From: "peer-a", To: "peer-b", BodySize: 320},
+ {TsUnixNano: 140, Event: EventATXSoftware, MessageType: protocol.MessageTypeText, MessageID: 3, From: "peer-a", To: "peer-b", BodySize: 320},
+ {TsUnixNano: 180, Event: EventBRXSoftware, MessageType: protocol.MessageTypeText, MessageID: 3, From: "peer-a", To: "peer-b", BodySize: 320},
+ {TsUnixNano: 220, Event: EventBAppRecv, MessageType: protocol.MessageTypeText, MessageID: 3, From: "peer-a", To: "peer-b", BodySize: 320},
+ {TsUnixNano: 260, Event: EventBPersistEnd, MessageType: protocol.MessageTypeText, MessageID: 3, From: "peer-a", To: "peer-b", BodySize: 320},
} {
if err := rawLogger.LogEvent(event); err != nil {
t.Fatalf("LogEvent() error = %v", err)
@@ -174,6 +183,9 @@ func TestLoadAndWriteSummaryFiles(t *testing.T) {
if got := ptrValue(summary.EndToEndLatencyNS); got != 160 {
t.Fatalf("EndToEndLatencyNS = %d, want 160", got)
}
+ if got := ptrValueFloat(summary.EndToEndBitrateBPS); got != 16_000_000_000 {
+ t.Fatalf("EndToEndBitrateBPS = %v, want 16000000000", got)
+ }
}
func ptrValue(value *int64) int64 {
@@ -182,3 +194,10 @@ func ptrValue(value *int64) int64 {
}
return *value
}
+
+func ptrValueFloat(value *float64) float64 {
+ if value == nil {
+ return 0
+ }
+ return *value
+}
diff --git a/cmd/internal/transport/tcp_linux.go b/cmd/internal/transport/tcp_linux.go
index 6578bf1..5641cc8 100644
--- a/cmd/internal/transport/tcp_linux.go
+++ b/cmd/internal/transport/tcp_linux.go
@@ -15,11 +15,11 @@ import (
)
const (
- linuxTimestampControlBufferSize = 2560 // 控制消息缓冲区。
- linuxSocketWriteBufferSize = 10 * 1024 * 1024 // 请求把 socket 发送缓冲区调到 10 MiB。
- linuxTXTimestampWaitTimeout = 250 * time.Millisecond // 等待 TX 时间戳的上限。
- linuxTXTimestampPollInterval = time.Millisecond // 轮询 errqueue 的间隔。
- linuxDataPollInterval = time.Millisecond // 轮询普通收发的间隔。
+ linuxTimestampControlBufferSize = 2048 // 控制消息缓冲区。
+ linuxSocketWriteBufferSize = 10 * 1024 * 1024 // 请求把 socket 发送缓冲区调到 10 MiB。
+ linuxTXTimestampWaitTimeout = 5000 * time.Millisecond // 等待 TX 时间戳的上限。
+ linuxTXTimestampPollInterval = time.Millisecond // 轮询 errqueue 的间隔。
+ linuxDataPollInterval = time.Millisecond // 轮询普通收发的间隔。
linuxSOTimestampingNew = 0x41
linuxSCMTimestampingNew = linuxSOTimestampingNew
diff --git a/latencysummary b/latencysummary
deleted file mode 100755
index e8ecfe9d81d13a42be9b5a474033b75547abc2dd..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 5642380
zcmeEv3w%`7wf9UOWD*k203jqiCpuIjJ`x4Y2*^YdI0w!^REnrrQ89vA#bhQy2{15;
z<~ST1y|lH}-dgLuwb!=V)*=rJnSg`<0wI-WRUSUhFem|(JP_vluf5NinS=!H>$~mu
z-SQ)6_Sw(1*IIk+wbx#IpJhez
ge;$~X1GbC4+u
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 |