Example of ProtocolBuf implemented by Java native Socket

1. Development environment

1.Protocol version: 3.9 (latest available) Download Address
2.Protocol Protocol Version: 3
3. Ordinary java environment, source code is 2 classes.

This is mainly about instant messaging using the native Java Socket API with its previous and back-end.Then binary data (Bytes) is generated from ProtocolBuf
) For network interaction, the code is easy to understand, suitable for getting started with instant messaging.Real projects start with a mature framework like nio, but the underlying principles are the same.(such as using Netty)

2. protocol Agreement Document

Front End Request Protocol File

syntax = "proto3";

option java_package = "com.asframe.pb3demo.proto";
option java_outer_classname = "LoginRequest";

message LoginReq
{
   //Logon Type
   int32 type = 1;
   //Name
   string name = 2;
   //Password
   string pass = 3;
}

Server-side return protocol file

syntax = "proto3";

option java_package = "com.asframe.pb3demo.proto";
option java_outer_classname = "LoginResponse";

message LoginRep 
{
   //Logon Results
   int32 result = 1;
   string msg = 2;
}

Note that the protocol architecture of Protocolbuf does not have a certain front-end and back-end.This is also a good place to manage by making a distinction between before and after protocols based on naming.You can also synthesize a file.
Execute the build corresponding structure instructions:

protoc -I=proto --java_out=src login_rep_msg.proto login_req_msg.proto

Generate corresponding java code from protocol file

3. Code

The code is simple and the comments are clear, so you can paste the code directly.
Anxious students can also download the source directly first

Download Source

Front End Code:

/**
 * Client Connection Test Example
 * @author sodaChen
 * @date 2019.07.06
 */
public class Client {

    public static void main(String[] args) throws Exception {
        //Front-end socket link
        Socket socket = new Socket("localhost", 19000);
        // Read DataInputStream from the server side
        DataInputStream in = new DataInputStream(socket.getInputStream());
        // DataOutputStream that sends information to the server
        DataOutputStream out = new DataOutputStream(socket.getOutputStream());

        //Construct a LoginReq object
        LoginRequest.LoginReq loginReq = LoginRequest.LoginReq.newBuilder()
                .setType(1)
                .setName("soda")
                .setPass("123456")
                .build();
        //Convert to bytes to calculate the size of pb protocol sent
        byte[] bodyBytes = loginReq.toByteArray();

        //Define the message body (message body content + previous version number size)
        out.writeShort(bodyBytes.length + 4);
        //Write version number
        out.writeShort(1);
        //Message directive, message directive is unique, return directive is 10000 more than send directive, that is 20001
        out.writeShort(10001);
        //Write message body
        out.write(bodyBytes);
        out.flush();

        //Receive server data here. Resolve the send protocol flow of the server, basically the client sends to the server similar
        //Receive message length size first
        short msgLength = in.readShort();
        //Message directives
        short cmd = in.readShort();
        //The remaining bytes are message bodies
        byte[] bytes = new byte[msgLength - 2];
        in.read(bytes);
        //This specifies that the server returns a protocol number of more than 1w.Actual projects should be well structured and handled dynamically here
        if(cmd == 20001)
        {
            LoginResponse.LoginRep loginRep = LoginResponse.LoginRep.parseFrom(bytes);
            System.out.println("Server returns data:" + loginRep);
        }
        //Closed Current
        out.close();
        System.out.println("client close");
    }
}

The process of parsing the service-side code is to parse it according to the format sent by the front-end.This is the basis of all communication.Specific rules can actually be formulated based on the needs of the project.

/**
 * protocolbuf3 Server-side processing
 * @author sodaChen
 * @date 2019.07.06
 */
public class Server
{
    public static void main(String[] args) throws Exception
    {
        //Establish Socket Server
        ServerSocket serverSocket = new ServerSocket(19000);
        System.out.println("The server socket start-up.");
        while (true)
        {
            //Listen for client connections
            Socket clientSocket = serverSocket.accept();
            System.out.println("There is a client connection up");
            // DataInputStream that reads information from clients
            DataInputStream in = new DataInputStream(clientSocket.getInputStream());
            // DataOutputStream that sends information to clients
            DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
            //Receive message length size first
            short msgLength = in.readShort();
            //Define the version of the message, currently not available
            short version = in.readShort();
            //Message directive, which is important for identifying what comes next in the message body
            short cmd = in.readShort();
            //The remaining bytes are the message body (minus four bytes of the degree already passed)
            byte[] bytes = new byte[msgLength - 4];
            //Direct reading
            in.read(bytes);
            //This directly determines the value of the cmd. If you do a project, the code here will be encapsulated at the bottom and should be parsed automatically, not manually
            if(cmd == 10001)
            {
                //Convert to Logon Request Object
                LoginRequest.LoginReq loginReq = LoginRequest.LoginReq.parseFrom(bytes);
                System.out.printf("loginReq:" + loginReq);
                //
                LoginResponse.LoginRep.Builder builder = LoginResponse.LoginRep.newBuilder();
                if(loginReq.getName().equals("soda"))
                {
                    builder.setResult(1);
                    builder.setMsg("Login Successful");
                }
                else
                {
                    builder.setResult(0);
                    builder.setMsg("Logon Failure");
                }
                //Create Login Return Object
                LoginResponse.LoginRep loginRep = builder.build();
                //Encapsulate message body to front end
                //Calculate Sent pb Protocol Size
                byte[] bodyBytes = loginRep.toByteArray();

                //Define message header (message body content + cmd size), server does not need to return version number
                out.writeShort(bodyBytes.length + 2);
                //Message directive, server returns 20001
                out.writeShort(20001);
                //Write message body
                out.write(bodyBytes);
                out.flush();
            }
        }
    }
}
92 original articles published. 72% praised. 780,000 visits+
His message board follow

Keywords: socket Java network Netty

Added by joeiscoolone on Fri, 06 Mar 2020 02:50:05 +0200