Streaming protocol specification
The SVST (SIGVIEW Stream) protocol is the binary wire format used by SIGVIEW's network streaming tools to transfer signal window data over TCP. This chapter documents the protocol so that third-party software can implement compatible senders or receivers.
Overview
•Transport: TCP (persistent connection)
•Byte order: Little-endian throughout
•Framing: Each data update is sent as a self-contained frame consisting of a fixed-size header followed by a variable-length payload
•Direction: Sender (server) transmits frames to connected receivers (clients). Communication is unidirectional -- the receiver does not send data back to the sender.
•Connection model: The sender listens on a TCP port. Receivers connect as clients. Multiple receivers may connect simultaneously.
Frame structure
Every frame consists of a 10-byte header followed by a payload whose size is specified in the header.
Header (10 bytes)
Offset Size Type Field Description
------ ---- ------ ----------- -----------
0 4 bytes Magic Fixed bytes 0x53 0x56 0x53 0x54
(ASCII "SVST"). Used to identify the
start of a frame and detect stream
misalignment.
4 1 uint8 Version Protocol version. Currently 1.
Receivers should reject frames with
an unsupported version.
5 1 uint8 WindowType Type of data in the payload:
1 = Signal Window
2 = Instrument Window (for future use)
6 4 uint32 PayloadSize Total size of the payload in bytes
(does not include the 10-byte header).
Reading frames from TCP
Because TCP is a stream protocol, a single recv() call may return fewer bytes than requested. Implementations must handle this by reading in a loop until the expected number of bytes has been received. The recommended approach:
1.Read exactly 10 bytes (the header).
2.Validate the magic bytes and version.
3.Read exactly PayloadSize bytes (the payload).
4.Deserialize the payload according to the WindowType.
Frames are sent back-to-back on the TCP stream with no delimiters between them. After processing one frame, the next frame's header follows immediately.
Signal Window payload (WindowType = 1)
The Signal Window payload carries all fields of the SigviewSignalWindow data type. Fields are serialized in the following fixed order:
# Type Field Description
-- --------- ---------------- -----------
1 float64 samplingRate Sampling rate of the signal. For
non-sampled data, this is
1.0 / (distance between values on x-axis).
2 float64 xAxisBegin Starting value of the x-axis.
Default is 0.0.
3 float64 signalBeginTime Absolute timestamp of the first sample,
expressed as seconds since
1970-01-01T00:00:00 UTC (Unix epoch).
Fractional seconds provide sub-second
precision.
4 uint8 lineColor Line color enumeration:
1 = COLOR_INPUT_SIGNAL (default)
2 = COLOR_ANALYSIS
3 = COLOR_TRACK
5 string xAxisUnit X-axis unit label (e.g., "Hz",
"seconds"). May be empty.
6 string yAxisUnit Y-axis unit label (e.g., "dB", "V").
May be empty.
7 string textToDisplay Optional overlay text displayed in the
upper-left corner of the window. Use \n
for line breaks. May be empty.
8 uint16 markerCount Number of markers that follow.
9 marker[] markers Repeated markerCount times. Each marker:
float64 -- x-axis position
string -- marker label text
10 uint32 sampleCount Number of signal samples that follow.
11 float32[] samples Signal values as an array of sampleCount
IEEE 754 single-precision (32-bit)
floating-point numbers in little-endian
byte order.
String encoding
All string fields use the same encoding:
Offset Size Type Description
------ -------- ------ -----------
0 2 uint16 Byte length of the UTF-8 encoded string.
May be 0 for an empty string.
2 length bytes UTF-8 encoded string content.
Not null-terminated.
Example: Signal Window frame (hex dump)
The following annotated hex dump shows a complete frame carrying a Signal Window with 4 samples at 1000 Hz sampling rate, no markers, and empty metadata strings:
-- Header (10 bytes) --
53 56 53 54 Magic: "SVST"
01 Version: 1
01 WindowType: 1 (Signal)
31 00 00 00 PayloadSize: 49 bytes
-- Payload --
00 00 00 00 00 40 8F 40 samplingRate: 1000.0 (float64)
00 00 00 00 00 00 00 00 xAxisBegin: 0.0 (float64)
00 00 00 00 00 00 00 00 signalBeginTime: 0.0 (float64, epoch)
01 lineColor: 1 (COLOR_INPUT_SIGNAL)
00 00 xAxisUnit: "" (length 0)
00 00 yAxisUnit: "" (length 0)
00 00 textToDisplay: "" (length 0)
00 00 markerCount: 0
04 00 00 00 sampleCount: 4
00 00 80 3F samples[0]: 1.0 (float32)
00 00 00 40 samples[1]: 2.0 (float32)
00 00 40 40 samples[2]: 3.0 (float32)
00 00 80 40 samples[3]: 4.0 (float32)
Implementation notes for third-party software
Implementing a receiver (client)
1.Open a TCP connection to the sender's IP address and port.
2.Read frames in a loop:
1.Read 10 bytes (header). Validate magic and version.
2.Read PayloadSize bytes. Deserialize according to WindowType.
3.On disconnect, optionally reconnect after a delay.
A minimal receiver only needs to parse the header and Signal Window payload. The textToDisplay, markers, and lineColor fields can safely be read and discarded if not needed.
Implementing a sender (server)
1.Listen on a TCP port and accept client connections.
2.For each data update, serialize a frame and write it to all connected clients.
3.Handle client disconnects gracefully (remove from client list on write failure).
Partial TCP reads
TCP does not preserve message boundaries. A single recv() call may return fewer bytes than requested, especially for large sample arrays. All implementations must read in a loop until the exact expected byte count has been received. The PayloadSize field in the header guarantees that the receiver always knows exactly how many bytes to expect.
Data types summary
Type name Size (bytes) Description
--------- ------------ -----------
uint8 1 Unsigned 8-bit integer
uint16 2 Unsigned 16-bit integer, little-endian
uint32 4 Unsigned 32-bit integer, little-endian
float32 4 IEEE 754 single-precision float, little-endian
float64 8 IEEE 754 double-precision float, little-endian
string 2 + n uint16 byte length followed by n bytes of UTF-8
Version compatibility
The protocol version field (currently 1) allows for future extensions. Receivers should reject frames with an unrecognized version number. Future versions will maintain backward compatibility by only adding new fields at the end of existing payloads or by introducing new WindowType values.