TCP Client Side Issue

本小妞迷上赌 提交于 2019-12-02 02:19:27

TCP is stream based, you get a stream of data from a client to server. You need to "deserialize" what you're expecting from the stream, if you can't build an application protocol that ensures each message sent is separately (which usually isn't a wise idea anyway with TCP).

So, you need to send with each message something that allows you to differentiate what the data is. This is often done with tag or type data at the start of each message. Sometimes a byte will do (depending on how many different message types you have). You then read that byte from the stream and decide what to deserialize next. e.g. if you want to send a string, you might serialize '1', then the string. If you want to send a date/time, you might serialize '2' then the DateTime. On the server, if both of those objects got sent about the same time, you could simply deserialize the byte, and if it was '1', deserialize a string, then continue deserializing: get the next byte, and if it's a '2', deserialize a DateTime.

It's important to remember that TCP is a stream-based protocol, not a message-based protocol. Message-based needs to be implemented at the application level--e.g. something like the above.

And by "serialize" and "deserialize" I mean the typical built-in serializers and deserializers as described in Serializing Objects in the .NET documentation. The same would hold true for JSON serializers included in libraries like JSON.NET or the built-in DataContractJsonSerializer and JavaScriptSerializer.

Just make sure that each message has its length as first few bytes, this way you can split the whole into single messages.

For example, suppose that you receive this 20 bytes message from your server:

                                        1                                       2
0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0

+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 2 | 4 | 6 | 1 | 5 | 3 | 3 | 2 | 6 | 3 | 4 | 1 | 6 | 2 | 3 | 5 | 3 | 0 | 4 | 6 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  ^           ^       ^               ^               ^           ^

The first byte says that the first message has 2 bytes of data, so you can retrive that message as bytes 1 and 2. Next you read byte 3 which tells you that the second message has only 1 byte of additional data (byte 4). The third and the fourth message have 3 bytes of data (as bytes 5 and 9 indicate), then there's a 2 bytes message and a 3 bytes one.

Using a fixed length header which contains at least the body length is the easiest way to go. Then depending on the body you might need additional information (like the type name if you want to use something like JSON to serialize/deserialize the actual message).

If you don't want to take care of everything yourself you could use a networking library like mine. Scroll down to the end of the article to see a JSON RPC sample implementation. You can take most of that to get a JSON based communication channel.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!