RPC's--HTTP protocol stack

Source: Internet
Author: User

Reprint Please specify source: http://blog.csdn.net/l1028386804/article/details/52531185

Today, to bring you a slightly deeper article-"RPC--http protocol stack", OK, let's get to the point.

The HTTP protocol belongs to the application-layer protocol, which is built on top of TCP and IP protocols, and it is located at the end of the architecture layer, so it does not deal with the cumbersome details such as packet replacement, handshake, fragmentation and reassembly of data, so that developers can focus on the application business.

Protocol is the specification of communication, in order to better understand the HTTP protocol, we can be based on the Java Socket API interface, through the design of a simple application layer communication protocol, to simple analysis of the implementation of the Protocol process and details.

In our example program today, the client sends a command to the server that, after receiving the command, determines whether the command is "Hello" and, if it is "hello", the response of the server to the client is "hello", otherwise the response returned by the server to the client is "Bye bye ”。

We then use Java to implement this simple application-layer communication protocol:

1. Definition of the Protocol request

The Protocol's requests mainly include: encoding, command, and command length three fields.

Package com.lyz.params;/** * Protocol Request definition * @author Liuyazhuang * */public class Request {/** * protocol encoded */private byte encode;/** * Command */private String command;/** * command length */private int commandlength;public Request () {super ();} Public Request (byte encode, String command, int commandlength) {super (); This.encode = Encode;this.command = Command;this. Commandlength = Commandlength;} Public byte Getencode () {return encode;} public void Setencode (byte encode) {This.encode = encode;} Public String GetCommand () {return command;} public void SetCommand (String command) {this.command = command;} public int getcommandlength () {return commandlength;} public void setcommandlength (int commandlength) {this.commandlength = Commandlength;} @Overridepublic String toString () {return "Request [encode=" + Encode + ", command=" + command+ ", commandlength=" + comma Ndlength + "]";}}

2. Definition of response protocol

The response of the Protocol mainly includes: encoding, response content and response length of three fields.

package com.lyz.params;/** * Definition of protocol response * @author Liuyazhuang * */public class Response {/** * encode */private byte encode;/** * Response content */ Private String response;/** * response length */private int responselength;public response () {super ();} Public Response (byte encode, String Response, int responselength) {super (); This.encode = Encode;this.response = Response; This.responselength = ResponseLength;} Public byte Getencode () {return encode;} public void Setencode (byte encode) {This.encode = encode;} Public String GetResponse () {return response;} public void Setresponse (String response) {this.response = response;} public int getresponselength () {return responselength;} public void setresponselength (int responselength) {this.responselength = ResponseLength;} @Overridepublic String toString () {return "Response [encode=" + Encode + ", response=" + response+ ", responselength=" + R Esponselength + "]";}} 

3. Definition of coded constants

The definition of coded constants mainly includes UTF-8 and GBK two kinds of coding.

Package com.lyz.constant;/** * Constant class * @author Liuyazhuang * */public final class Encode {//utf-8 encoded public static final byte UTF8 = 1;//GBK encoded public static final byte GBK = 2;}

4, the implementation of the client

The client constructs a request, sends it to the remote through the socket interface, and receives the remote response information and constructs a response object.

Package Com.lyz.protocol.client;import Java.io.ioexception;import Java.io.inputstream;import java.io.OutputStream; Import Java.net.socket;import com.lyz.constant.encode;import Com.lyz.params.request;import com.lyz.params.Response Import com.lyz.utils.protocolutils;/** * Client code * @author Liuyazhuang * */public Final class Client {public static void Ma In (string[] args) throws ioexception{//requests Request request = new request (); Request.setcommand ("HELLO"); Request.setcommandlength (Request.getcommand (). Length ()); Request.setencode (Encode.utf8); Socket client = new socket ("127.0.0.1", 4567); OutputStream out = Client.getoutputstream ();// Send Request Protocolutils.writerequest (out, request);//Read response data InputStream in = Client.getinputstream (); Response Response = Protocolutils.readresponse (in); SYSTEM.OUT.PRINTLN ("Get response result information is:" + response.tostring ());}}

5, the implementation of the service side

The server receives a request from the client, responds to different message information depending on the receive command, and responds with "Hello" if the "hello" command otherwise responds to "Bye Bye" information.

Package Com.lyz.protocol.server;import Java.io.ioexception;import Java.io.inputstream;import java.io.OutputStream; Import Java.net.serversocket;import java.net.socket;import com.lyz.constant.encode;import com.lyz.params.Request; Import Com.lyz.params.response;import com.lyz.utils.protocolutils;/** * server-side code * @author Liuyazhuang * */public final  Class Server {public static void main (string[] args) throws Ioexception{serversocket Server = new ServerSocket (4567); (true) {Socket client = server.accept ();//Read request data InputStream input = Client.getinputstream (); Request Request = Protocolutils.readrequest (input); SYSTEM.OUT.PRINTLN ("Request parameter Received:" + request.tostring ()); OutputStream out = Client.getoutputstream ();//Assembly Response data response Response = new Response (), Response.setencode (Encode.utf8), if ("HELLO". Equals (Request.getcommand ())) { Response.setresponse ("Hello");} Else{response.setresponse ("Bye Bye");} Response.setresponselength (Response.getresponse (). Length ()); Protocolutils.writeresponse (out, response);}}} 

6, the realization of Protocolutils tool class

Protocolutils's Readrequest method reads the requested encode, command, and commandlength three parameters from the input stream that is passed in, making the corresponding encoding conversion and constructing the request object to return. The Writeresponse method, in turn, writes the fields of the response object to the output stream of the response according to the corresponding encoding.

There is one detail that needs to be emphasized: writing an int type directly in the OutputStream will intercept its low 8 bits and discard its high 24 bits, so the corresponding conversion action is required when the data is passed and received.

Package Com.lyz.utils;import Java.io.ioexception;import Java.io.inputstream;import java.io.outputstream;import Com.lyz.constant.encode;import Com.lyz.params.request;import com.lyz.params.response;/** * Protocol Tool class * @author Liuyazhuang * */public Final class Protocolutils {/** * Deserialize the request object from the input stream * @param input * @return * @throws IOException */public static Request readrequest (InputStream input) throws ioexception{//read encoding byte[] Encodebyte = new Byte[1]; Input.read (encodebyte); byte encode = encodebyte[0];//Read command length byte[] commandlengthbytes = new Byte[4];input.read ( commandlengthbytes); int commandlength = Byteutils.byte2int (commandlengthbytes);//Read command byte[] commandbytes = new byte[ Commandlength];input.read (commandbytes); string command = ""; if (Encode.utf8 = = Encode) {command = new String (commandbytes, "UTF-8");} else if (ENCODE.GBK = = Encode) {command = new String (commandbytes, "GBK");} Assembly requests return Request request = new request (encode, command, commandlength); return request;} /** * Deserialize the response object from the input stream * @parAM Input * @return * @throws ioexception */public static Response readresponse (InputStream input) throws ioexception{//read Code byte[] Encodebyte = new Byte[1];input.read (encodebyte); byte encode = encodebyte[0];//Read response length byte[] Responselengthbytes = new Byte[4];input.read (responselengthbytes); int responselength = Byteutils.byte2int (responselengthbytes);// Read command byte[] responsebytes = new Byte[responselength];input.read (responsebytes); String response = "", if (Encode.utf8 = = Encode) {response = new String (responsebytes, "UTF-8");} else if (ENCODE.GBK = = Encode) {response = new String (responsebytes, "GBK");} Assembly request returned Response resp = new Response (encode, Response, responselength); return resp;} /** * Serialization Request Information * @param output * @param response */public static void Writerequest (OutputStream output, request request) th Rows ioexception{//Returns the response response to the client Output.write (Request.getencode ());//output.write (response.getresponselength ()); direct write an int type intercepts the low 8-bit transmit drop high 24-bit output.write (Byteutils.int2bytearray (Request.getcommanDlength ())), if (Encode.utf8 = = Request.getencode ()) {Output.write (Request.getcommand (). GetBytes ("UTF-8"));} else if (ENCODE.GBK = = Request.getencode ()) {Output.write (Request.getcommand (). GetBytes ("GBK"));} Output.flush ();}  /** * Serialization of response information * @param output * @param response */public static void Writeresponse (OutputStream output, response response) Throws ioexception{//returns the response response to the client Output.write (Response.getencode ());//output.write ( Response.getresponselength ()); direct write an int type intercepts a low 8-bit transfer drop high 24-bit output.write (Byteutils.int2bytearray ( Response.getresponselength ())), if (Encode.utf8 = = Response.getencode ()) {Output.write (Response.getresponse ()). GetBytes ("UTF-8"));} else if (ENCODE.GBK = = Response.getencode ()) {Output.write (Response.getresponse (). GetBytes ("GBK"));} Output.flush ();}}

7, the realization of Byteutils class

Package com.lyz.utils;/** * Byte conversion tool class * @author Liuyazhuang * */public final class Byteutils {/** * Converts a byte array to an int number * @param Bytes * @return */public static int byte2int (byte[] bytes) {int num = bytes[3] & 0xff;num |= ((bytes[2] << 8) &A mp 0XFF00) Num |= ((bytes[1] <<) & 0xFF0000), Num |= ((bytes[0] <<) & 0xff000000); return num;} /** * Convert int type number to byte array * @param num * @return */public static byte[] Int2bytearray (int i) {byte[] result = new Byte[4];res Ult[0]  = (byte) ((I >>) & 0xFF); result[1]  = (byte) ((I >> +) & 0xFF); result[2]  = (by TE) ((I >> 8) & 0xFF); result[3]  = (byte) (I & 0xFF); return result;}}
At this point, we have developed the application-Layer Communication protocol sample code.

RPC's--HTTP protocol stack

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.