[{"data":1,"prerenderedAt":623},["ShallowReactive",2],{"guide-binary-data-network-protocols":3},{"id":4,"title":5,"body":6,"date":615,"description":616,"extension":617,"meta":618,"navigation":184,"path":619,"readingTime":194,"seo":620,"stem":621,"__hash__":622},"guides\u002Fguides\u002Fbinary-data-network-protocols.md","Binary Data in Network Protocols",{"type":7,"value":8,"toc":603},"minimark",[9,14,31,34,37,87,90,94,97,107,110,115,118,273,276,280,283,289,292,321,324,328,339,368,375,458,464,468,479,485,488,492,565,569,586,590,599],[10,11,13],"h2",{"id":12},"why-protocols-use-binary","Why Protocols Use Binary",[15,16,17,18,22,23,26,27,30],"p",{},"Text-based formats like JSON and XML are easy for humans to read. But network protocols favor binary encoding for three reasons: ",[19,20,21],"strong",{},"compactness",", ",[19,24,25],{},"parsing speed",", and ",[19,28,29],{},"determinism",".",[15,32,33],{},"A binary protocol assigns fixed byte positions and bit widths to every field. The parser reads bytes at known offsets — no string splitting, no quote escaping, no ambiguity. This makes binary protocols faster to parse and smaller on the wire.",[15,35,36],{},"Consider a simple message carrying a temperature reading:",[38,39,40,56],"table",{},[41,42,43],"thead",{},[44,45,46,50,53],"tr",{},[47,48,49],"th",{},"Format",[47,51,52],{},"Representation",[47,54,55],{},"Bytes",[57,58,59,74],"tbody",{},[44,60,61,65,71],{},[62,63,64],"td",{},"JSON",[62,66,67],{},[68,69,70],"code",{},"{\"temp\":23.5}",[62,72,73],{},"14",[44,75,76,79,84],{},[62,77,78],{},"Binary (float32 + 1 byte ID)",[62,80,81],{},[68,82,83],{},"\\x01\\x41\\xbc\\x00\\x00",[62,85,86],{},"5",[15,88,89],{},"The binary version is 64% smaller. At scale — thousands of messages per second — this difference compounds into meaningful bandwidth savings.",[10,91,93],{"id":92},"binary-in-tcpip-headers","Binary in TCP\u002FIP Headers",[15,95,96],{},"The TCP header is a classic binary protocol. Each field occupies a fixed bit range:",[98,99,104],"pre",{"className":100,"code":102,"language":103},[101],"language-text"," 0                   1                   2                   3\n 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|          Source Port          |       Destination Port        |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|                        Sequence Number                        |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|                    Acknowledgment Number                      |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|  Data |           |U|A|P|R|S|F|                               |\n| Offset| Reserved  |R|C|S|S|Y|I|            Window             |\n|       |           |G|K|H|T|N|N|                               |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n","text",[68,105,102],{"__ignoreMap":106},"",[15,108,109],{},"Every field has a precise byte position and bit width. The parser knows exactly where to find the source port (bytes 0-1), the sequence number (bytes 4-7), and the flags (bits in byte 13).",[111,112,114],"h3",{"id":113},"bit-level-operations","Bit-Level Operations",[15,116,117],{},"Reading binary protocol fields requires bitwise operations:",[98,119,123],{"className":120,"code":121,"language":122,"meta":106,"style":106},"language-javascript shiki shiki-themes github-light github-dark","\u002F\u002F Read source port from TCP header (bytes 0-1, big-endian)\nconst sourcePort = (header[0] \u003C\u003C 8) | header[1];\n\n\u002F\u002F Read the SYN flag (bit 1 of byte 13)\nconst synFlag = (header[13] & 0x02) !== 0;\n\n\u002F\u002F Read data offset (upper 4 bits of byte 12)\nconst dataOffset = (header[12] >> 4) * 4; \u002F\u002F in bytes\n","javascript",[68,124,125,134,179,186,192,226,231,237],{"__ignoreMap":106},[126,127,130],"span",{"class":128,"line":129},"line",1,[126,131,133],{"class":132},"sJ8bj","\u002F\u002F Read source port from TCP header (bytes 0-1, big-endian)\n",[126,135,137,141,145,148,152,155,158,161,164,167,170,173,176],{"class":128,"line":136},2,[126,138,140],{"class":139},"szBVR","const",[126,142,144],{"class":143},"sj4cs"," sourcePort",[126,146,147],{"class":139}," =",[126,149,151],{"class":150},"sVt8B"," (header[",[126,153,154],{"class":143},"0",[126,156,157],{"class":150},"] ",[126,159,160],{"class":139},"\u003C\u003C",[126,162,163],{"class":143}," 8",[126,165,166],{"class":150},") ",[126,168,169],{"class":139},"|",[126,171,172],{"class":150}," header[",[126,174,175],{"class":143},"1",[126,177,178],{"class":150},"];\n",[126,180,182],{"class":128,"line":181},3,[126,183,185],{"emptyLinePlaceholder":184},true,"\n",[126,187,189],{"class":128,"line":188},4,[126,190,191],{"class":132},"\u002F\u002F Read the SYN flag (bit 1 of byte 13)\n",[126,193,195,197,200,202,204,207,209,212,215,217,220,223],{"class":128,"line":194},5,[126,196,140],{"class":139},[126,198,199],{"class":143}," synFlag",[126,201,147],{"class":139},[126,203,151],{"class":150},[126,205,206],{"class":143},"13",[126,208,157],{"class":150},[126,210,211],{"class":139},"&",[126,213,214],{"class":143}," 0x02",[126,216,166],{"class":150},[126,218,219],{"class":139},"!==",[126,221,222],{"class":143}," 0",[126,224,225],{"class":150},";\n",[126,227,229],{"class":128,"line":228},6,[126,230,185],{"emptyLinePlaceholder":184},[126,232,234],{"class":128,"line":233},7,[126,235,236],{"class":132},"\u002F\u002F Read data offset (upper 4 bits of byte 12)\n",[126,238,240,242,245,247,249,252,254,257,260,262,265,267,270],{"class":128,"line":239},8,[126,241,140],{"class":139},[126,243,244],{"class":143}," dataOffset",[126,246,147],{"class":139},[126,248,151],{"class":150},[126,250,251],{"class":143},"12",[126,253,157],{"class":150},[126,255,256],{"class":139},">>",[126,258,259],{"class":143}," 4",[126,261,166],{"class":150},[126,263,264],{"class":139},"*",[126,266,259],{"class":143},[126,268,269],{"class":150},"; ",[126,271,272],{"class":132},"\u002F\u002F in bytes\n",[15,274,275],{},"These operations translate directly to how the protocol specification defines each field.",[10,277,279],{"id":278},"binary-in-websocket-frames","Binary in WebSocket Frames",[15,281,282],{},"WebSocket uses a binary framing protocol on top of TCP. Each frame has a header that encodes metadata in specific bits:",[98,284,287],{"className":285,"code":286,"language":103},[101]," 0                   1                   2                   3\n 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|F|R|R|R| opcode|M| Payload len |    Extended payload length    |\n|I|S|S|S|  (4)  |A|     (7)     |             (16\u002F64)           |\n|N|V|V|V|       |S|             |   (if payload len==126\u002F127)   |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n",[68,288,286],{"__ignoreMap":106},[15,290,291],{},"Key details:",[293,294,295,303,309,315],"ul",{},[296,297,298,299,302],"li",{},"The ",[19,300,301],{},"FIN bit"," (bit 0) indicates the last frame in a message",[296,304,298,305,308],{},[19,306,307],{},"opcode"," (bits 4-7) distinguishes text frames (0x1) from binary frames (0x2)",[296,310,298,311,314],{},[19,312,313],{},"MASK bit"," indicates whether the payload is XOR-masked (required for client-to-server frames)",[296,316,298,317,320],{},[19,318,319],{},"payload length"," uses 7 bits for lengths 0-125, with 126 and 127 as escape codes for 16-bit and 64-bit lengths",[15,322,323],{},"This compact header adds only 2-14 bytes per frame — far less than an HTTP-style text header.",[10,325,327],{"id":326},"endianness-in-network-protocols","Endianness in Network Protocols",[15,329,330,331,334,335,338],{},"Binary protocols must specify byte order (",[19,332,333],{},"endianness","). Network protocols use ",[19,336,337],{},"big-endian"," (also called network byte order) by convention.",[98,340,342],{"className":120,"code":341,"language":122,"meta":106,"style":106},"\u002F\u002F Big-endian: most significant byte first\n\u002F\u002F Value 0x1234 stored as [0x12, 0x34]\n\n\u002F\u002F Little-endian (common on x86 CPUs): least significant byte first\n\u002F\u002F Value 0x1234 stored as [0x34, 0x12]\n",[68,343,344,349,354,358,363],{"__ignoreMap":106},[126,345,346],{"class":128,"line":129},[126,347,348],{"class":132},"\u002F\u002F Big-endian: most significant byte first\n",[126,350,351],{"class":128,"line":136},[126,352,353],{"class":132},"\u002F\u002F Value 0x1234 stored as [0x12, 0x34]\n",[126,355,356],{"class":128,"line":181},[126,357,185],{"emptyLinePlaceholder":184},[126,359,360],{"class":128,"line":188},[126,361,362],{"class":132},"\u002F\u002F Little-endian (common on x86 CPUs): least significant byte first\n",[126,364,365],{"class":128,"line":194},[126,366,367],{"class":132},"\u002F\u002F Value 0x1234 stored as [0x34, 0x12]\n",[15,369,370,371,374],{},"JavaScript's ",[68,372,373],{},"DataView"," lets you specify endianness explicitly:",[98,376,378],{"className":120,"code":377,"language":122,"meta":106,"style":106},"const view = new DataView(buffer);\nconst port = view.getUint16(0, false); \u002F\u002F offset 0, big-endian\nconst length = view.getUint32(2, false); \u002F\u002F offset 2, big-endian\n",[68,379,380,399,430],{"__ignoreMap":106},[126,381,382,384,387,389,392,396],{"class":128,"line":129},[126,383,140],{"class":139},[126,385,386],{"class":143}," view",[126,388,147],{"class":139},[126,390,391],{"class":139}," new",[126,393,395],{"class":394},"sScJk"," DataView",[126,397,398],{"class":150},"(buffer);\n",[126,400,401,403,406,408,411,414,417,419,421,424,427],{"class":128,"line":136},[126,402,140],{"class":139},[126,404,405],{"class":143}," port",[126,407,147],{"class":139},[126,409,410],{"class":150}," view.",[126,412,413],{"class":394},"getUint16",[126,415,416],{"class":150},"(",[126,418,154],{"class":143},[126,420,22],{"class":150},[126,422,423],{"class":143},"false",[126,425,426],{"class":150},"); ",[126,428,429],{"class":132},"\u002F\u002F offset 0, big-endian\n",[126,431,432,434,437,439,441,444,446,449,451,453,455],{"class":128,"line":181},[126,433,140],{"class":139},[126,435,436],{"class":143}," length",[126,438,147],{"class":139},[126,440,410],{"class":150},[126,442,443],{"class":394},"getUint32",[126,445,416],{"class":150},[126,447,448],{"class":143},"2",[126,450,22],{"class":150},[126,452,423],{"class":143},[126,454,426],{"class":150},[126,456,457],{"class":132},"\u002F\u002F offset 2, big-endian\n",[15,459,460,461,463],{},"Always pass ",[68,462,423],{}," (big-endian) when reading network protocol data.",[10,465,467],{"id":466},"binary-in-dns-messages","Binary in DNS Messages",[15,469,470,471,474,475,478],{},"DNS queries and responses use a binary format where even domain names are compressed. Instead of repeating ",[68,472,473],{},"example.com"," in every record, DNS uses ",[19,476,477],{},"pointer compression"," — an offset that points back to a previously encoded name.",[98,480,483],{"className":481,"code":482,"language":103},[101],"Normal:     \\x07example\\x03com\\x00           (13 bytes)\nCompressed: \\xc0\\x0c                          (2 bytes — pointer to offset 12)\n",[68,484,482],{"__ignoreMap":106},[15,486,487],{},"This compression can reduce DNS message sizes by 50% or more in responses with many records sharing the same domain suffix.",[10,489,491],{"id":490},"practical-binary-tools","Practical Binary Tools",[38,493,494,507],{},[41,495,496],{},[44,497,498,501,504],{},[47,499,500],{},"Task",[47,502,503],{},"Tool",[47,505,506],{},"Use Case",[57,508,509,525,540,554],{},[44,510,511,514,522],{},[62,512,513],{},"Inspect raw bytes",[62,515,516,22,519],{},[68,517,518],{},"xxd",[68,520,521],{},"hexdump",[62,523,524],{},"Debug binary protocol data",[44,526,527,530,537],{},[62,528,529],{},"Parse in JavaScript",[62,531,532,22,534],{},[68,533,373],{},[68,535,536],{},"ArrayBuffer",[62,538,539],{},"Read\u002Fwrite binary in browsers",[44,541,542,545,551],{},[62,543,544],{},"Parse in Python",[62,546,547,550],{},[68,548,549],{},"struct"," module",[62,552,553],{},"Unpack binary structs",[44,555,556,559,562],{},[62,557,558],{},"Capture traffic",[62,560,561],{},"Wireshark",[62,563,564],{},"Analyze live protocol data",[10,566,568],{"id":567},"key-takeaways","Key Takeaways",[293,570,571,574,577,580,583],{},[296,572,573],{},"Binary protocols are more compact and faster to parse than text-based alternatives",[296,575,576],{},"Fields occupy fixed bit positions — parsers read bytes at known offsets using bitwise operations",[296,578,579],{},"TCP, WebSocket, and DNS all use binary framing for efficiency",[296,581,582],{},"Network byte order is big-endian; always specify endianness when reading binary data",[296,584,585],{},"Understanding binary encoding helps you debug protocol issues and write efficient parsers",[10,587,589],{"id":588},"try-it-yourself","Try It Yourself",[15,591,592,593,598],{},"Convert text to binary and back to see how characters map to bytes using our ",[594,595,597],"a",{"href":596},"\u002Ftools\u002Ftext-binary","Text to Binary"," tool. Paste any text, inspect the binary representation, and understand byte-level encoding firsthand.",[600,601,602],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}",{"title":106,"searchDepth":136,"depth":136,"links":604},[605,606,609,610,611,612,613,614],{"id":12,"depth":136,"text":13},{"id":92,"depth":136,"text":93,"children":607},[608],{"id":113,"depth":181,"text":114},{"id":278,"depth":136,"text":279},{"id":326,"depth":136,"text":327},{"id":466,"depth":136,"text":467},{"id":490,"depth":136,"text":491},{"id":567,"depth":136,"text":568},{"id":588,"depth":136,"text":589},"2026-05-28","Understand how network protocols use binary encoding — from TCP headers to WebSocket frames — and why binary beats text for performance.","md",{"immutable":184},"\u002Fguides\u002Fbinary-data-network-protocols",{"title":5,"description":616},"guides\u002Fbinary-data-network-protocols","zvVzz9UbViE5LYcAyPejH2k8RqLn6cVFZRZNz2MO2Ag",1780401331724]