1"use strict";(self.webpackChunkgatsby_starter_default=self.webpackChunkgatsby_starter_default||[]).push([[236],{24043:function(n,s,a){a.r(s),a.d(s,{Head:function(){return b},default:function(){return f}});var e=a(28453),t=a(96540);function p(n){const s=Object.assign({p:"p",span:"span",blockquote:"blockquote",a:"a",h2:"h2"},(0,e.R)(),n.components);return t.createElement(t.Fragment,null,t.createElement(s.p,null,"If you ever face a task that involves tricky low-level network communication, you have to consider that network might (and most likely will) partition data that are being sent over."),"\n",t.createElement(s.p,null,"Letâs say, there is a TCP server that receives messages from clients. When a client connects to the server and pushes some bytes to a socket, if the size of the data is small enough, the whole message will be sent as a single chunk. But if the size of the data is above a certain limit, the message will be split into multiple chunks. So you have to take care of concatenating these chunks on the receiving side."),"\n",t.createElement(s.p,null,"Consider a client sends two messages â ",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">hello</code>'}})," and ",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">world</code>'}})," â one after another. Depending on a network, the server might receive these messages in two chunks, i.e.:"),"\n",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">hello\nworld</code></pre></div>'}}),"\n",t.createElement(s.p,null,"Or in four chunks:"),"\n",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">hel\nlo\nwor\nld</code></pre></div>'}}),"\n",t.createElement(s.p,null,"In case if data is under your control and you can be sure that a payload wouldn't contain some special character, such as a line feed, then you can use it as a delimiter to indicate the end of a message. I.e. once a receiver encounters ",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">\\n</code>'}})," byte, it means the message is fully received."),"\n",t.createElement(s.p,null,"But in case if a payload is arbitrary user input, it is not reliable to rely on delimiters of any kind. The solution is to encode a length of a message into a payload sent to a receiving part."),"\n",t.createElement(s.blockquote,null,"\n",t.createElement(s.p,null,"I will be using Rust for code samples, but the pattern should be language agnostic, hence portable to any general-purpose programming language."),"\n"),"\n",t.createElement(s.p,null,"When sending a string, it needs to be represented as bytes first:"),"\n",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="rust"><pre class="language-rust"><code class="language-rust"><span class="token comment">// "hello".as_bytes()</span>\n<span class="token punctuation">[</span><span class="token number">104</span><span class="token punctuation">,</span> <span class="token number">101</span><span class="token punctuation">,</span> <span class="token number">108</span><span class="token punctuation">,</span> <span class="token number">108</span><span class="token punctuation">,</span> <span class="token number">111</span><span class="token punctuation">]</span></code></pre></div>'}}),"\n",t.createElement(s.p,null,"The length of this message is ",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">5</code>'}}),". To transfer this information to a receiver, we can get a memory representation of this integer in ",t.createElement(s.a,{href:"https://en.wikipedia.org/wiki/Endianness"},"big-endian")," byte order."),"\n",t.createElement(s.p,null,"Both parties must agree on a type of this integer. I will elaborate on why in a sec."),"\n",t.createElement(s.p,null,"Let's pick a ",t.createElement(s.a,{href:"https://doc.rust-lang.org/std/primitive.u32.html"},t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">u32</code>'}}
1))," as a type for a length. In Rust, a size of 32-bit unsigned integer (",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">u32</code>'}}),") is ",t.createElement(s.a,{href:"https://doc.rust-lang.org/std/mem/fn.size_of.html"},"4 bytes"),". So the memory representation of ",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">5</code>'}})," of type ",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">u32</code>'}})," is:"),"\n",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="rust"><pre class="language-rust"><code class="language-rust"><span class="token comment">// 5 as u32</span>\n<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span></code></pre></div>'}}),"\n",t.createElement(s.p,null,"We can get this representation by calling ",t.createElement(s.a,{href:"https://doc.rust-lang.org/std/primitive.u32.html#method.to_be_bytes"},t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">to_be_bytes</code>'}}))," method."),"\n",t.createElement(s.p,null,"Now, we can concatenate these 2 arrays and shape a payload: the bytes that will be sent over the network."),"\n",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="rust"><pre class="language-rust"><code class="language-rust"><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">104</span><span class="token punctuation">,</span> <span class="token number">101</span><span class="token punctuation">,</span> <span class="token number">108</span><span class="token punctuation">,</span> <span class="token number">108</span><span class="token punctuation">,</span> <span class="token number">111</span><span class="token punctuation">]</span></code></pre></div>'}}),"\n",t.createElement(s.p,null,"When the receiver sees new data, it must take the first 4 bytes and convert them back to a 32-bit integer to get the length of the incoming message. This is why the type is so important: 16-bit unsigned integer (",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">u16</code>'}}),") would take 2 bytes, so the receiver would need to eject 2 first bytes instead of 4 and use a different function for the conversion."),"\n",t.createElement(s.p,null,"When the length of the message is known, the receiver keeps reading bytes from the socket into some buffer until the size of the buffer is equal to the length of the message."),"\n",t.createElement(s.p,null,"Consider the case, when a network splits the message above into two chunks."),"\n",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="rust"><pre class="language-rust"><code class="language-rust"><span class="token comment">// first chunk:</span>\n<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">104</span><span class="token punctuation">,</span> <span class="token number">101</span><span class="token punctuation">]</span>\n\n<span class="token comment">// length: [0, 0, 0, 5] -> 5</span>\n<span class="token comment">// buffer: [104, 101]</span></code></pre></div>'}}),"\n",t.createElement(s.p,null,"Since the length of the buffer is only ",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">2</code>'}}),", the receiver knows that this is only a part of the message, so it waits for the next chunk."),"\n",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="rust"><pre class="language-rust"><code class="language-rust"><span class="token comment">// second chunk:</span>\n<span class="token punctuation">[</span><span class="token number">108</span><span class="token punctuation">,</span> <span class="token number">108</span><span class="token punctuation">,</span> <span class="token number">111</span><span class="token punctuation">]</span>\n\n<span class="token comment">// buffer: [104, 101, 108, 108, 111]</span></code></pre></div>'}}),"\n",t.createElement(s.p,null,"Now, the length of the buffer is ",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">5</code>'}}),", which means the whole message was received and it can be used for whatever."),"\n",t.createElement(s.h2,{id:"show-me-the-code",style:{position:"relative"}}
1,t.createElement(s.a,{href:"#show-me-the-code","aria-label":"show me the code permalink",className:"anchor before"},t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Show me the code"),"\n",t.createElement(s.p,null,"Implementation of a TCP client-server pair, where the client sends a string to the server and the server prints messages to a stdout."),"\n",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="rust"><pre class="language-rust"><code class="language-rust"><span class="token comment">// client.rs</span>\n\n<span class="token keyword">let</span> <span class="token keyword">mut</span> socket <span class="token operator">=</span> <span class="token class-name">TcpStream</span><span class="token punctuation">::</span><span class="token function">connect</span><span class="token punctuation">(</span><span class="token string">"127.0.0.1:7080"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token keyword">await</span><span class="token operator">?</span><span class="token punctuation">;</span>\n\n<span class="token keyword">let</span> message <span class="token operator">=</span> <span class="token string">b"hello"</span><span class="token punctuation">;</span>\n\n<span class="token comment">// cast to u32 is critical to get an array of exactly 4 bytes</span>\n<span class="token keyword">let</span> message_len <span class="token operator">=</span> message<span class="token punctuation">.</span><span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token keyword">u32</span><span class="token punctuation">;</span>\n\n<span class="token comment">// Getting the memory representation of the message length (u32)</span>\n<span class="token comment">// as a byte array in big-endian (network) byte order</span>\n<span class="token keyword">let</span> message_len_bytes <span class="token operator">=</span> message_len<span class="token punctuation">.</span><span class="token function">to_be_bytes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n<span class="token comment">// Concatenating the message length and the message itself</span>\n<span class="token keyword">let</span> <span class="token keyword">mut</span> bytes <span class="token operator">=</span> message_len_bytes<span class="token punctuation">.</span><span class="token function">to_vec</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\nbytes<span class="token punctuation">.</span><span class="token function">extend</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n<span class="token comment">// Waiting for the socket to be writable</span>\nsocket<span class="token punctuation">.</span><span class="token function">writable</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token keyword">await</span><span class="token operator">?</span><span class="token punctuation">;</span>\n\n<span class="token comment">// Writing bytes to the socket</span>\nsocket<span class="token punctuation">.</span><span class="token function">write_all</span><span class="token punctuation">(</span><span class="token operator">&</span>bytes<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token keyword">await</span><span class="token operator">?</span><span class="token punctuation">;</span></code></pre></div>'}}),"\n",t.createElement(s.p,null,"And the server half:"),"\n",t.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="rust"><pre class="language-rust"><code class="language-rust"><span class="token comment">// @file: server.rs</span>\n\n<span class="token keyword">let</span> listener <span class="token operator">=</span> <span class="token class-name">TcpListener</span><span class="token punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token string">"127.0.0.1:7080"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token keyword">await</span><span class="token operator">?</span><span class="token punctuation">;</span>\n\n<span class="token keyword">loop</span> <span class="token punctuation">{</span>\n <span class="token comment">// New connection</span>\n <span class="token keyword">let</span> <span class="token punctuation">(</span>socket<span class="token punctuation">,</span> addr<span class="token punctuation">)</span> <span class="token operator">=</span> listener<span class="token punctuation">.</span><span class="token function">accept</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token keyword">await</span><span class="token operator">?</span><span class="token punctuation">;</span>\n\n <span class="token comment">// Spawning a new task to handle each connection asynchronously</span>\n <span class="token namespace">task<span class="token punctuation">::</span></span><span class="token function">spawn</span><span class="token punctuation">(</span><span class="token keyword">async</span> <span class="token keyword">move</span> <span class="token punctuation">{</span>
1\n <span class="token macro property">println!</span><span class="token punctuation">(</span><span class="token string">"[{}] new connection"</span><span class="token punctuation">,</span> addr<span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n <span class="token comment">// Buffer for an incoming message</span>\n <span class="token keyword">let</span> <span class="token keyword">mut</span> buf <span class="token operator">=</span> <span class="token class-name">Vec</span><span class="token punctuation">::</span><span class="token function">new</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token comment">// Length of the current message</span>\n <span class="token keyword">let</span> <span class="token keyword">mut</span> len <span class="token operator">=</span> <span class="token class-name">None</span><span class="token punctuation">;</span>\n\n <span class="token keyword">loop</span> <span class="token punctuation">{</span>\n <span class="token comment">// Waiting for the socket to be readable</span>\n socket<span class="token punctuation">.</span><span class="token function">readable</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token keyword">await</span><span class="token punctuation">.</span><span class="token function">unwrap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n <span class="token keyword">match</span> socket<span class="token punctuation">.</span><span class="token function">try_read_buf</span><span class="token punctuation">(</span><span class="token operator">&</span><span class="token keyword">mut</span> buf<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token class-name">Ok</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n <span class="token comment">// Ok(0) indicates the streamâs read half is closed</span>\n <span class="token comment">// and will no longer yield data</span>\n <span class="token keyword">break</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n <span class="token class-name">Ok</span><span class="token punctuation">(</span>_<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n <span class="token comment">// Some bytes were read and placed in the buffer.</span>\n <span class="token comment">// First, figuring out the length of the whole message.</span>\n <span class="token keyword">let</span> message_len <span class="token operator">=</span> <span class="token keyword">match</span> len <span class="token punctuation">{</span>\n <span class="token class-name">None</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n <span class="token comment">// No current length set.</span>\n <span class="token comment">// It means that either this is</span>\n <span class="token comment">// the very first message from this client,</span>\n <span class="token comment">// or the previous message was received</span>\n <span class="token comment">// and `buf` + `len` have been reset.</span>\n\n <span class="token comment">// Taking first 4 bytes out of the buffer.</span>\n <span class="token comment">// This is the length of the whole message.</span>
1\n <span class="token keyword">let</span> len_bytes <span class="token operator">=</span> buf\n <span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span><span class="token punctuation">..</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token macro property">vec!</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span>\n <span class="token punctuation">.</span><span class="token function">collect</span><span class="token punctuation">::</span><span class="token operator"><</span><span class="token class-name">Vec</span><span class="token operator"><</span><span class="token keyword">u8</span><span class="token operator">>></span><span class="token punctuation">(</span><span class="token punctuation">)</span>\n <span class="token punctuation">.</span><span class="token function">try_into</span><span class="token punctuation">(</span><span class="token punctuation">)</span>\n <span class="token punctuation">.</span><span class="token function">unwrap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n <span class="token comment">// Converting these bytes into u32</span>\n <span class="token keyword">u32</span><span class="token punctuation">::</span><span class="token function">from_be_bytes</span><span class="token punctuation">(</span>len_bytes<span class="token punctuation">)</span>\n <span class="token punctuation">}</span>\n <span class="token class-name">Some</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n <span class="token comment">// `len` is already set, which means a head</span>\n <span class="token comment">// of the message was already received.</span>\n n\n <span class="token punctuation">}</span>\n <span class="token punctuation">}</span><span class="token punctuation">;</span>\n\n <span class="token keyword">if</span> message_len <span class="token keyword">as</span> <span class="token keyword">usize</span> <span class="token operator">==</span> buf<span class="token punctuation">.</span><span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token comment">// Buffer length is equal to message length,</span>\n <span class="token comment">// means the whole message has been received</span>\n <span class="token keyword">let</span> message <span class="token operator">=</span> <span class="token namespace">std<span class="token punctuation">::</span></span><span class="token keyword">str</span><span class="token punctuation">::</span><span class="token function">from_utf8</span><span class="token punctuation">(</span><span class="token operator">&</span>buf<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">unwrap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n <span class="token comment">// Simply printing it to stdout</span>\n <span class="token macro property">println!</span><span class="token punctuation">(</span><span class="token string">"[{}] message: {}"</span><span class="token punctuation">,</span> addr<span class="token punctuation">,</span> message<span class="token punctuation">)</span><span class="token punctuation">;</span>
1\n\n <span class="token comment">// Resetting the buffer and the current length</span>\n buf<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n len <span class="token operator">=</span> <span class="token class-name">None</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> message_len <span class="token keyword">as</span> <span class="token keyword">usize</span> <span class="token operator">></span> buf<span class="token punctuation">.</span><span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token comment">// Buffer length is less then message length,</span>\n <span class="token comment">// means the buffer contains only a part</span>\n <span class="token comment">// of the message</span>\n len <span class="token operator">=</span> <span class="token class-name">Some</span><span class="token punctuation">(</span>message_len<span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>\n <span class="token comment">// Shouldn\'t be a case</span>\n <span class="token macro property">panic!</span><span class="token punctuation">(</span><span class="token string">"Message length < current buffer"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n <span class="token punctuation">}</span>\n <span class="token comment">// If for whatever reason socket is unreadable, retrying</span>\n <span class="token class-name">Err</span><span class="token punctuation">(</span><span class="token keyword">ref</span> err<span class="token punctuation">)</span> <span class="token keyword">if</span> err<span class="token punctuation">.</span><span class="token function">kind</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token namespace">io<span class="token punctuation">::</span></span><span class="token class-name">ErrorKind</span><span class="token punctuation">::</span><span class="token class-name">WouldBlock</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n <span class="token keyword">continue</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n <span class="token class-name">Err</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token macro property">panic!</span><span class="token punctuation">(</span><span class="token string">"[{}] {}"</span><span class="token punctuation">,</span> addr<span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">,</span>\n <span class="token punctuation">}</span>\n <span class="token punctuation">}</span>\n <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span></code></pre></div>'}}),"\n",t.createElement(s.p,null,"You can poke this code by forking ",t.createElement(s.a,{href:"https://github.com/alexfedoseev/blog-post-sending-bytes"},"this repo"),"."),"\n",t.createElement(s.p,null,"Have fun!"))}var o=function(n){void 0===n&&(n={});const{wrapper:s}=Object.assign({},(0,e.R)(),n.components);return s?t.createElement(s,n,t.createElement(p,n)):p(n)},c=a(5588),l=a(65427),u=a(20504),r=a(43397),i=a(61942);const k=n=>n.replace(/\/+$/,""),m=(n,s)=>s?""+n+(s.startsWith("/")?s:"/"+s):n,g=(n,s)=>m(k(n),s),d=(n,s)=>m((n=>
1"undefined"!=typeof window?window.location.origin:k(n))(n),s),h=(n,s)=>{const a=(0,c.d)(s);return a?g(n,a):(n=>g(n,"/shakacode-og.png"))(n)},y=n=>{let{data:s,location:a,children:e}=n;const{frontmatter:p}=s.mdx,{siteUrl:o}=s.site.siteMetadata,c=d(o,a.pathname);return t.createElement(t.Fragment,null,t.createElement(l.A,null),t.createElement(u.A,{header:t.createElement(i.r,{breadcrumb:p.title}),main:t.createElement(t.Fragment,null,t.createElement(i.c,{body:e,title:p.title,author:p.author,date:p.date,link:c,categories:p.categories,featuredImage:p.featuredImage,showFeaturedImage:p.showFeaturedImage}),t.createElement(r.LN,null))}))};function f(n){return t.createElement(y,n,t.createElement(o,n))}const b=n=>{let{data:s,location:a}=n;const{frontmatter:e,excerpt:p}=s.mdx,{siteMetadata:o}=s.site,{siteUrl:c,title:l,description:u}=o,r=((n,s,a)=>n.excerpt||s||a)(e,p,u),i=h(c,e.featuredImage),k=g(c,a.pathname);return t.createElement(t.Fragment,null,t.createElement("title",null,e.title+" | "+l),t.createElement("link",{rel:"canonical",href:k}),t.createElement("meta",{name:"description",content:r}),t.createElement("meta",{property:"og:title",content:e.title}),t.createElement("meta",{property:"og:description",content:r}),t.createElement("meta",{property:"og:type",content:"article"}),t.createElement("meta",{property:"og:url",content:k}),t.createElement("meta",{property:"og:image",content:i}),t.createElement("meta",{name:"image",content:i}),t.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),t.createElement("meta",{name:"twitter:title",content:e.title}),t.createElement("meta",{name:"twitter:description",content:r}),t.createElement("meta",{name:"twitter:image",content:i}))}}}]); 2//# sourceMappingURL=component---src-template-blog-article-tsx-content-file-path-src-posts-sending-bytes-index-mdx-fd20fb4838fd30a47cb4.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.