How to compare a slice to a string ?

xuanbao · · 113 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>msg := make([]byte, 1024)</p> <p>I made a udp server for my game , and I want if the client send &#34;Let&#39;s play&#34; it runs a specific func else it runs nothing . </p> <hr/>**评论:**<br/><br/>jerf: <pre><p>One easy option is to compare []byte to []byte directly: <a href="https://golang.org/pkg/bytes/#Equal" rel="nofollow">bytes.Equal</a></p> <p>This is skipping a discussion of protocol design that the other thread is getting into, which for now I&#39;ll just handwave at <a href="https://en.wikipedia.org/wiki/Type-length-value" rel="nofollow">type-length-value (TLV)</a> and call it a day. Broadly speaking, you probably don&#39;t want your protocol to <em>literally</em> involve sending a bare string &#34;Let&#39;s play&#34;, but you could be using that just as an example.</p></pre>nevyn: <pre><blockquote> <p>This is skipping a discussion of protocol design that the other thread is getting into, which for now I&#39;ll just handwave at type-length-value (TLV) and call it a day</p> </blockquote> <p>Is TLV a real thing implemented anywhere? That page is pretty hard to decipher (where are the values for command_c etc. ... why aren&#39;t the quotes included in the length).</p> <p>It kind of looks like a simple list of Key/Value pairs which is fine, but why not use something like <a href="https://en.wikipedia.org/wiki/Netstring" rel="nofollow">netstrings</a> for each or if you really want more readability then something like a simplified form of <a href="https://en.wikipedia.org/wiki/Bencode" rel="nofollow">bencoding</a>. </p></pre>jerf: <pre><p>No, it&#39;s a category of things, of which netstrings and bencoding are examples. I just wanted to reference the ideas, not get too prescriptive. The Internet is based on quite a few textual protocols, and they have some advantages, but they require a certain amount of code infrastructure to obtain their advantages, and they are also shot through with subtle-but-very-important issues that can be difficult for early programmers to understand and mitigate.</p> <p>Binary protocols are much easier to bootstrap, most notably because one of the things you can do is just use length-delimited strings to create an unambiguous textual protocol. If you use &#34;2 or 4 bytes of length in network order, then than much string&#34;, you will save a lot of headache vs. trying to just send the strings down the wire. (In the case of UDP, 2 is the most you can count on.)</p> <p>As the protocols grow, well, each type of protocol has its own massive traps in it. But I think for quick prototyping work and for earlier programmers, a TLV-esque protocol is in the sweet spot of easy enough to program, easy enough to understand, easy enough to extend, and easy enough to grow for quite a while. (Many other important protocols like TLS are fundamentally TLV at the core; it can grow with you all the way to that scale.)</p> <p>Lately I&#39;ve been using:</p> <ul> <li>1 byte of length of the next string</li> <li>that much string, indicating the type of the message</li> <li>4 bytes of length of next string</li> <li>that much JSON</li> </ul> <p>Then my Go code can:</p> <ol> <li>Read the type of the next message and create a struct based on it to be passed to the JSON decoder.</li> <li>Read the length of the next message, and create an io.LimitedReader off of the underlying stream for a JSON decoder.</li> <li>Decode the JSON into the struct.</li> <li>Exhaust the rest of the limited reader.</li> <li>Return it.</li> </ol> <p>It&#39;s a really quick &amp; simple protocol. (It&#39;s so easy to implement that it&#39;s at times faster to just implement this and leverage the JSON capabilities of the language than to read the documentation of something that may be awesome, like protocol buffers or something, but which requires Effort to integrate.)</p> <p>(4 is paranoia; it covers the case where the JSON encoder used by the other side adds extra whitespace to the end, like a \n. Go&#39;s encoder doesn&#39;t, so if you use Go on both sides you can skip it, but then things will explode if you ever use a non-Go on the other end.)</p></pre>nevyn: <pre><p>Yeh, I agree with all that ... I guess the wikipedia page just needs a lot of love. I would add that using JSON as the message is nice to get something up an running but is much less fun for everyone, in a public protocol.</p></pre>icholy: <pre><p>You can use <code>bytes.HasPrefix</code></p> <p><a href="https://play.golang.org/p/x16k5FUnRvM" rel="nofollow">https://play.golang.org/p/x16k5FUnRvM</a></p></pre>TrueFurby: <pre><p>Try something like this: <a href="https://play.golang.org/p/jfCs11ZOZy2" rel="nofollow">https://play.golang.org/p/jfCs11ZOZy2</a></p></pre>upboatact: <pre><p>the naive way would be to convert the slice into a string, and than simply check for equality <code>string(msg) == &#34;Let&#39;s play&#34;</code></p> <p>it is naive for a reason though, don&#39;t do that if it matters</p></pre>TrueFurby: <pre><p>That would not work without first making them the same length: <a href="https://play.golang.org/p/F_L5MnRR6HX" rel="nofollow">https://play.golang.org/p/F_L5MnRR6HX</a></p></pre>upboatact: <pre><p>sure, that is yet another detail that needs attention: re-slicing the original slice with the length returned by Read</p></pre>TrueFurby: <pre><p>Yes, this is important because my original solution will match even strings like &#34;Let&#39;s play or not&#34;. So the best would be to start comparing only amount of bytes received and not full buffer.</p></pre>
113 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传