Detailed introduction to C # Common protocol implementation template and Fixedsizereceivefilter sample code

Source: Internet
Author: User
Tags app service
This article mainly introduces the common protocol implementation template and Fixedsizereceivefilter example. Have a good reference value, follow the small series together to see it

The protocol resolution inside the socket is the most complicated part of the socket Communication program design, and if your application layer protocol is poorly designed or implemented, the common sticky packets in the socket can be difficult to avoid. SuperSocket has built-in command-line protocol Commandlineprotocol, if you use protocols in other formats, you must implement your own custom protocol customprotocol. After reading a document, you may find it not easy to use SuperSocket to implement your custom protocol. To make this easier, SuperSocket provides a number of common protocol resolution tools that you can use to implement your own communication protocols simply and quickly:

    • Terminatorreceivefilter (SuperSocket.SocketBase.Protocol.TerminatorReceiveFilter, Supersocket.socketbase)---Terminator protocol

    • Countspliterreceivefilter (SuperSocket.Facility.Protocol.CountSpliterReceiveFilter, supersocket.facility)---fixed number separator protocol

    • Fixedsizereceivefilter (SuperSocket.Facility.Protocol.FixedSizeReceiveFilter, supersocket.facility)---Fixed request size protocol

    • Beginendmarkreceivefilter (SuperSocket.Facility.Protocol.BeginEndMarkReceiveFilter, supersocket.facility)---with end-to-end character protocol

    • Fixedheaderreceivefilter (SuperSocket.Facility.Protocol.FixedHeaderReceiveFilter, supersocket.facility)---Header format fixed and contains content length protocol

1. Terminatorreceivefilter Terminator Protocol

The Terminator protocol and the command-line protocol are similar, and some protocols use a terminator to determine a request. For example, a protocol uses the two-character "# #" as the Terminator, so you can use the class "Terminatorreceivefilterfactory":

Terminator Protocol Terminatorprotocolserver:

public class terminatorprotocolserver:appserver{public  terminatorprotocolserver ()  : Base (new Terminatorreceivefilterfactory ("# #")) {}}

Implement your receive filter (Receivefilter) based on Terminatorreceivefilter:

public class yourreceivefilter:terminatorreceivefilter<yourrequestinfo>{//more code}

Implement your receive filter factory (receivefilterfactory) to create an accept filter instance:

public class yourreceivefilterfactory:ireceivefilterfactory<yourrequestinfo>{//more code}

2. Countspliterreceivefilter Fixed Number Separator protocol

Some protocols define requests such as "#part1 #part2#part3#part4#part5#part6#part7#" in such a format. Each request has 7 sections separated by a ' # '. The implementation of this Protocol is very simple:

<summary>///Request Format: #part1 #part2#part3#part4#part5#part6#part7#///</summary>public class countspliterappserver:appserver{public Countspliterappserver ()  : Base (New Countspliterreceivefilterfactory ( byte) ' # ', 8))//8 separators, 7 parameters. In addition to using the default filter factory, you can also reference the previous instance custom protocol {}}

3. Fixedsizereceivefilter Fixed Request size protocol

In such a protocol, all requests are of the same size. If each of your requests is a string of 8 characters, such as "HUANG LI", what you should do is to implement a receive filter (Receivefilter) like the following code:

Class myreceivefilter:fixedsizereceivefilter<stringrequestinfo>{public Myreceivefilter ()  : Base (8)// Incoming fixed request size {} protected override Stringrequestinfo Processmatchedrequest (byte[] buffer, int offset, int length, bool Tobec opied) {  //todo: Constructs the request instance through the parsed data and returns}}

Then use this accept filter (Receivefilter) in your AppServer class:

public class myappserver:appserver{Public myappserver ()  : base (New defaultreceivefilterfactory< Myreceivefilter, stringrequestinfo> ())//using the default Accept Filter factory (defaultreceivefilterfactory) {}}

4, Beginendmarkreceivefilter with the beginning and end of the agreement

There are fixed start and end tags in each request for this type of protocol. For example, I have an agreement that all of its messages follow this format "&xxxxxxxxxxxxxx#". So, in this case, "&" is the start tag, "#" is the end tag, so your acceptance filter can be defined like this:

Class myreceivefilter:beginendmarkreceivefilter<stringrequestinfo>{//Start and end tags can also be two or more than two bytes private readonly Static byte[] Beginmark = new byte[] {(byte) ' & '}; Private readonly static byte[] Endmark = new byte[] {(byte) ' # '}; Public Myreceivefilter ()  : Base (Beginmark, Endmark)//Incoming start tag and end tag {} protected override Stringrequestinfo Processmatchedrequest (byte[] readbuffer, int offset, int length) {  //todo: Constructs the request instance through the parsed data and returns}}

Then use this accept filter (Receivefilter) in your AppServer class:

public class myappserver:appserver{Public myappserver ()  : base (New defaultreceivefilterfactory< Myreceivefilter, stringrequestinfo> ())//using the default Accept Filter factory (defaultreceivefilterfactory) {}}

5. Fixedheaderreceivefilter header format fixed and contains content length protocol

This protocol defines a request as two parts, and the first part defines the basic information including the second part length, and so on. We usually call the first part head.

For example, we have one such protocol: the header contains 6 bytes, the first 4 bytes are used to store the requested name, and the last two bytes are used to represent the length of the request body:

+-------+---+-------------------------------+///|request| L |                               | /// | Name  | e |    Request Body               |///|  (4)  | n |                               | /// |       | (2) |                               | /// +-------+---+-------------------------------+

With SuperSocket, you can implement this protocol very conveniently:

Class myreceivefilter:fixedheaderreceivefilter<binaryrequestinfo>{public Myreceivefilter ()  : Base (6) {}  protected override int Getbodylengthfromheader (byte[] header, int offset, int length) {  return (int) Header[offset + 4] * + (int) Header[offset + 5]; } protected override Binaryrequestinfo Resolverequestinfo (arraysegment<byte> header, byte[] bodybuffer, int Offset, int length) {  return new Binaryrequestinfo (Encoding.UTF8.GetString (header). Array, header. Offset, 4), Bodybuffer.clonerange (offset, length)); }}

You need to implement your own receive filter based on the class Fixedheaderreceivefilter.

    • The 6 passed in to the parent class constructor represents the length of the head;

    • The method "Getbodylengthfromheader (...)" should return the length of the request body according to the received header;

    • Method Resolverequestinfo (...) "The instance of your request type should be returned based on the request header and the request body you received.

Actual usage scenarios:

Here are the five types of protocol templates you've already learned and know about formatting. Next look at a network example:

Communication protocol Format:

After seeing the protocol is sent 16 in the tangled client, the server how to receive, 16 binary messages are as follows:

26 01 00 19 4E 4A 30 31 31 01 44 41 31 31 32 00 07 00 00 00 00 00 00 34 23

16 into the system, 10 or more, the other into the system, and ultimately converted to byte[], in fact, when processing data, send the past data can be converted into byte[], so the service as long as the resolution byte[] array on the line. You can get the data you want by parsing the protocol. The following example uses Fixedsizereceivefilter, the code is as follows:

Based on the above communication protocol, start to implement the parsing:

The first step, defining a data structure that is appropriate for the Protocol

Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading.Tasks;/*** Author: Twilight before dawn * CLR version: 4.0.30319.42000* created on: 2017-01-23 21:12:30* 2017* Description: Protocol packet * * Modification history: *******************************************************************/namespace supersocketdemo{public class Hldata {//<summary>///Start sign///</summary> public char Head {get; set;  }///<summary>///package data///</summary> public byte Ping {get; set;}  <summary>///Data length///</summary> public ushort Lenght {get; set;}  <summary>///terminal ID///</summary> public uint FID {get; set;}  <summary>////target type///</summary> public byte type {get; set;}  <summary>///Forwarding terminal ID///</summary> public uint SID {get; set;}  <summary>////Send count///</summary> public ushort Sendcount {get; set;} <summary>///reserved fields///</summary> public byte[] Retain {get; set;}  <summary>//XOR Check///</summary> public byte Check {get; set;}  <summary>///end symbol///</summary> public char end {get; set;} public override string ToString () {return string. Format ("start symbol: {0}, packet data: {1}, data length: {2}, terminal id:{3}, Target type: {4}, forwarding terminal id:{5}, send packet count: {6}, reserved field: {7}, XOR: {8}  , lenght, FID, Type, SID, Sendcount, Retain, Check, End); }}}hldata

Step two, establish a requestinfo to receive the server data

Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading.Tasks; Using supersocket.socketbase.protocol;/***************************************************************** Author: Twilight before dawn * CLR version: 4.0.30319.42000* created: 2017-01-22 21:03:31* 2017* Description: Data Request * * Revision history: ************************************ /namespace supersocketdemo{public class hlprotocolrequestinfo:requestinfo< hldata> {public  hlprotocolrequestinfo (hldata hldata)  {   //If you need to use a command-line protocol, the command class name Hldata the same   Initialize ("Hldata", Hldata);  } }}hlprotocolrequestinfo class

The third step, Fixedsize protocol resolution

Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading.Tasks; Using supersocket.socketbase.protocol;using supersocket.facility.protocol;using supersocket.common;/************* Author: Twilight before dawn * CLR version: 4.0.30319.42000* created: 2017-01-22 21:06:01* 2017* Description: Protocol resolution class, fixed request-SIZE protocol * * Modified history: *******************************************************************/namespace supersocketdemo{//<summary>///Fixed request size protocol (frame format hlprotocolrequestinfo)///</summary> public class hlprotocolreceivefilter:fixedsizereceivefilter

Fourth step, set up agreement factory Hlreceivefilterfactory

Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading.Tasks; Using supersocket.socketbase;using supersocket.socketbase.protocol;using system.net;/**************************** Author: Twilight before dawn * CLR version: 4.0.30319.42000* creation time: 2017-01-23:22:01:25* 2017* Description: Protocol Factory * * Revision history: *******************************************************************/namespace SuperSocketDemo{public class hlreceivefilterfactory:ireceivefilterfactory

Fifth step, custom hlprotocolsession inheritance Appsession

Using supersocket.socketbase;using supersocket.socketbase.protocol;using system;/******************************** Author: Twilight before dawn * CLR version: 4.0.30319.42000* created: 2017-01-22 21:15:11* 2017* Description: Custom hlprotocolsession** modification History: *******************************************************************/namespace supersocketdemo{public class Hlprotocolsession:appsession

Sixth step, custom Hlprotocolserver inheritance AppServer

Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading.Tasks; Using supersocket.socketbase;using supersocket.socketbase.protocol;/********************************************  Author: Twilight before dawn *  CLR version: 4.0.30319.42000*  created: 2017-01-22 21:16:57*  2017*  Description: Custom server**  modification history: *******************************************************************/namespace supersocketdemo{public class Hlprotocolserver:appserver

The seventh step, plus the end-to-end protocol Hlbeginendmarkreceivefilter

Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading.Tasks; Using supersocket.common;using supersocket.facility.protocol;/************************************************** Author: Twilight before dawn * CLR version: 4.0.30319.42000* created: 2017-01-23 22:07:03* 2017* Description: Protocol with a start and end character, "&" is the opening tag, "#" is a knot Bundle marker, start end tag defined by yourself * * Modify history: *******************************************************************/namespace    supersocketdemo{public class Hlbeginendmarkreceivefilter:beginendmarkreceivefilter

step Eighth, service start and stop

Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading.Tasks; Using supersocket.socketbase;using supersocket.socketbase.protocol;using supersocket.socketengine;/**************  Author: Twilight before dawn * CLR version: 4.0.30319.42000* created: 2017-01-19 00:02:17* 2017* Description: Service start and stop entry * * Revision history: 2017-01-19 Adjust custom mysession and myserver* 2017-01-23 Communication protocol resolution, directly using the Ingress registration event ****************** /namespace supersocketdemo{class Program {//<summary>// /SuperSocket service start or stop///</summary>//<param name= "args" ></param> static void Main (string[] A      RGS) {Console.WriteLine ("Please press any key to start SuperSocket service!");      Console.readkey ();      Console.WriteLine ();      var hlprotocolserver = new Hlprotocolserver ();      Set port number int port = 2017; Start the app service port if (! Hlprotocolserver.setup (port)//Listening port at startup {Console.wriTeline ("Service port failed to start!");        Console.readkey ();      Return      } Console.WriteLine ();      Register Connection Event Hlprotocolserver.newsessionconnected + = hlprotocolserver_newsessionconnected;      Registration Request Event Hlprotocolserver.newrequestreceived + = hlprotocolserver_newrequestreceived;      Register session Shutdown Event hlprotocolserver.sessionclosed + = hlprotocolserver_sessionclosed; Try to start the app service if (!        Hlprotocolserver.start ()) {Console.WriteLine ("Service failed to start!");        Console.readkey ();      Return      } Console.WriteLine ("Server Status:" + HLProtocolServer.State.ToString ());      Console.WriteLine ("Service started successfully, please press ' E ' to stop the service!"); while (Console.readkey ().        KeyChar! = ' E ') {Console.WriteLine ();      Continue      }//Stop service hlprotocolserver.stop ();      Console.WriteLine ("Service has stopped!");    Console.readkey ();      } static void Hlprotocolserver_sessionclosed (Hlprotocolsession session, SuperSocket.SocketBase.CloseReason value) { Console.WriteLine (session. REmoteendpoint.tostring () + "connection disconnected.    Disconnect reason: "+ value"; } static void Hlprotocolserver_newsessionconnected (Hlprotocolsession session) {Console.WriteLine (session).    Remoteendpoint.tostring () + "connected."); }///<summary>///The protocol does not have much complex logic, do not need to use the command mode, directly in this way can///</summary>//<param Name= "session "></param>//<param name=" Requestinfo "></param> private static void Hlprotocolserver_newreque      Streceived (hlprotocolsession session, Hlprotocolrequestinfo Requestinfo) {Console.WriteLine (); Console.WriteLine ("Data Source:" + Session.)      Remoteendpoint.tostring ());    Console.WriteLine ("Receive Data content:" +requestinfo.body); }}}program Class

Communication protocol requires the use of small tools for debugging, I am using the TCP/UDP port debugging tool Sockettool V2. You can download it directly. Send 16 message using hex mode, server output result:

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.