msg := make([]byte, 1024)
I made a udp server for my game , and I want if the client send "Let's play" it runs a specific func else it runs nothing .
评论:
jerf:
nevyn:One easy option is to compare []byte to []byte directly: bytes.Equal
This is skipping a discussion of protocol design that the other thread is getting into, which for now I'll just handwave at type-length-value (TLV) and call it a day. Broadly speaking, you probably don't want your protocol to literally involve sending a bare string "Let's play", but you could be using that just as an example.
jerf:This is skipping a discussion of protocol design that the other thread is getting into, which for now I'll just handwave at type-length-value (TLV) and call it a day
Is TLV a real thing implemented anywhere? That page is pretty hard to decipher (where are the values for command_c etc. ... why aren't the quotes included in the length).
It kind of looks like a simple list of Key/Value pairs which is fine, but why not use something like netstrings for each or if you really want more readability then something like a simplified form of bencoding.
No, it'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.
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 "2 or 4 bytes of length in network order, then than much string", 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.)
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.)
Lately I've been using:
- 1 byte of length of the next string
- that much string, indicating the type of the message
- 4 bytes of length of next string
- that much JSON
Then my Go code can:
- Read the type of the next message and create a struct based on it to be passed to the JSON decoder.
- Read the length of the next message, and create an io.LimitedReader off of the underlying stream for a JSON decoder.
- Decode the JSON into the struct.
- Exhaust the rest of the limited reader.
- Return it.
It's a really quick & simple protocol. (It's so easy to implement that it'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.)
(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's encoder doesn'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.)
nevyn:icholy: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.
TrueFurby:You can use
bytes.HasPrefix
upboatact:Try something like this: https://play.golang.org/p/jfCs11ZOZy2
TrueFurby:the naive way would be to convert the slice into a string, and than simply check for equality
string(msg) == "Let's play"
it is naive for a reason though, don't do that if it matters
upboatact:That would not work without first making them the same length: https://play.golang.org/p/F_L5MnRR6HX
TrueFurby:sure, that is yet another detail that needs attention: re-slicing the original slice with the length returned by Read
Yes, this is important because my original solution will match even strings like "Let's play or not". So the best would be to start comparing only amount of bytes received and not full buffer.
