In the previous articleArticleAt the end of the section, I pasted the framework part from me. I believe you are also very interested in it, and I will continue to introduce you to the wonderful im technology without confidentiality.
In this article, I will explain the design of im-based UDP Communication Protocol (1)
Have you used QQ? Frequently Used? Do you know how QQ works? Will QQ be split? As an im researcher, we often need to analyze existing market products.
QQ is based on the UDP communication protocol. There is no doubt that I will analyze QQ (taking qq2009 as an example ):
When you open QQ, several UDP ports (4000 ~ 6000) two segments are accumulated in sequence. At that time, I was wondering, why did he open so many ports? Is it necessary to open so many ports?
Well, the preface. Now we will begin to explain this article.
Most of the current instant messaging software uses UDP for the following reasons:
1. The UDP protocol does not need to keep saving the user socket, that is, disconnected, which saves resources.
2. Convenience of forwarding various messages to the server
3. In order to better reduce exceptions (for example, when using TCP/IP ?)
I also used the UDP communication protocol in the project. For a general frame chart, I can see the previous article. Why do I open so many ports like QQ?
I would like to explain to you that as an im writer, we need to maintain a concept at all times:A QQ can support different protocol clusters, and each protocol cluster includes various commands of the protocol cluster.
This is why QQ has opened multiple UDP ports, because in order to support different protocols !!
I want to read this article. Many people write C/S software, do they have only one protocol?
Don't you understand? For example, your IM registration, Login User, get user information, chat .. Are all group operations and friend operations enabled with one UDP port?
If not, why is that so much?
After receiving this UDP port, you will see a "command tree" (commonly known as "command tree"). To put it bluntly, it is nothing more than the following form:
Code
// Determine the second parameter through the first parameter to call different processing methods.
Switch (Sp_orders [ 0 ])
{
// Modify information command
Case " Update " :
// Determine the project to be modified
Switch (Sp_orders [ 1 ])
{
// Modify personal signature
Case " Pro " :
This . Updatetodata ( " Pro " , Sp_orders [ 2 ], Sp_orders [ 3 ]);
Break ;
// Modify nickname
Case " Nickname " :
Break ;
// Modify age
Case " Age " :
Break ;
// Modify personal details
Case " Info " :
Break ;
// Update online Port
Case " Port " :
// Pass QQ and online Port
This . Port = Sp_orders [ 3 ];
This . Number_myself = Sp_orders [ 2 ];
This . Update2port (sp_orders [ 2 ], Sp_orders [ 3 ]);
Break ;
// Others
Default :
Return ;
}
Break ;
// Chat command
Case " Chk_online " :
This . Chk_user_online (sp_orders [ 1 ]); // Call the method for detecting user launch
Break ;
// Other cases
Default :
Break ; Please do not learn the above method. I will give an example to illustrate the knowledge so that people who do not understand it can understand it. This command tree is not good, because what? 1. If I have many commands (usually many IM protocols), isn't it highly coupled? And there will be a lotCodeWritten in a method body. 2. It looks trivial... Don't you think? Here is just a brief introduction, so let's talk about the port based on which QQ opens (for example ): We have defined an enumeration:
Code
Public EnumNetworkprotocol
{
Base, // supports common protocol clusters (common interaction with servers)
File_transfer, // File Transfer Protocol Cluster
Video, // video protocol cluster
Voice // voice protocol cluster
}
So it is clear that Im has been optimized in a better way.Program, We will specify a port for each protocol cluster.
In this case, there are four UDP listeners, right?
Well, now we need to continue with the last explanation. We have successfully listened to four UDP ports using the included portlistener and messagelistener,
What? You won't use the command tree to judge the command ?????
How can we develop our ideas to achieve low coupling, easy maintenance, simplicity, and convenience?
I have put forward my project experience here, and I will give you a correct solution to this problem.
Let me give a rough look at our communication. As UDP communication, we will have two very large enumerations, one called "in_network_command" and the other called
"Out_network_command", you will understand the benefits later.
Well, "in_network_command" is mainly used to save the package protocol commands I have currently received
"Out_network_command" is mainly used to save the packet protocol commands we want to send
Let's take a look at the two enumerations in my project (included in my UML communication framework ):
I don't know. Can you tell the secret? Well, you will surely see me, "in_network_command" and "out_network_command"
They all correspond to each other. This is the solution!
ThatOkay. Let's continue. What was the earliest protocol we defined?
I will provide the protocol for most people (such as logon ):LOgin $ username {**} password {**} {| * end * |}
This is the custom protocol that many people have seen about user login. The other party has a very good idea: "After I receive such a command, first of all, check whether {| * end * |} exists}
If yes, of course this command is complete. Then, use {**} to separate the command to get the user name and password !"
Well, I don't want to talk about this friend's custom protocol commands, because I will explain the correct solution in the project in the next explanation, this instance uses this protocol as a metaphor:
How can we differentiate the protocol cluster to which the current protocol belongs? Do you still remember the protocol cluster enumeration we just defined? The enum type can be converted to int!
This is enough, so we can add:
LOgin $ username {**} password {**} 0 (<-- this 0 indicates the protocol cluster number, which is strongly converted from enumeration) {**} {| * end * |}
Now, we have inserted the Protocol number to which the command belongs in the Custom command. We will continue to modify it without using the login $ header as the custom command header, we also used the method just now to rename the command number you wanted.
From the command enumeration, convert to int
In this case, the custom command becomes:
Username {**} password {**} 0 (<-- this 0 indicates the protocol cluster number, which is strongly converted from enumeration) {**} 0 (<-- this 0 indicates the command number, which is strongly converted from enumeration) {**} {| * end * |}
Oh, does it look more comfortable this time? Most people may think that what is the benefit of this? Do I still need to split it on the server?
This is a lot of benefit, and I will explain to you in the next lesson why it works better to use command numbers, so I will tell you in advance.
The question to be explained next time is "My im-basics [3]-im design based on UDP Communication [network communication protocol based on XML format]"
What are the specific advantages of interest?
Now, let's review the content of this explanation:
1. Incorrect command tree writing
2. Threw out custom communication protocol commands and corrected some parameters.
3. Explains why multiple UDP ports are enabled.
4. The concept of protocol cluster enumeration is proposed.
5. A preliminary scheme for enumerating User-Defined Protocol commands (in/out) is proposed.
Are you satisfied with this explanation? The following is a wonderful introduction !!!