Android-based PROTOBUF socket Communication development tutorial

Source: Internet
Author: User
Tags getmessage getstream readline static class stringbuffer

Protobuf the applicable language

Authentic (Google's own in-house) Protobuf supports three languages: Java, C + +, and Pyton, and unfortunately does not support languages such as. Net or Lua, but the power of the community cannot be overlooked because PROTOBUF is indeed more than JSON, XML has the advantage of speed and ease of use, and can be forward-compatible, backward-compatible and so many features, so the PROTOBUF community has a protobuf.net component and also support a number of languages, detailed to see this link: http:// Code.google.com/p/protobuf/wiki/thirdpartyaddons, the use of a specific language, please separate, this article is only to use Android and C + + server communication (test) or with the PC communication, using Java and C #之间互相通讯方面的DEMO, the readers do reference.


using the PROTOBUF protocol

Define PROTOBUF protocol

To define the PROTOBUF protocol you must create a file with the. proto suffix, for example, this article creates a message file called Msg.proto, which reads as follows:

The code is as follows Copy Code



Package msginfo;





Message cmsg


{


Required String msghead = 1;


Required String msgbody = 2;


}





Message Cmsghead


{


Required Int32 msglen = 1;


Required Int32 msgtype = 2;


Required Int32 msgseq = 3;


Required Int32 termversion = 4;


Required Int32 msgres = 5;


Required String termid = 6;


}





Message Cmsgreg


{


Optional int32 area = 1;


Optional Int32 region = 2;


Optional Int32 shop = 3;


Optional int32 ret = 4;


Optional String termid = 5[defalut= "12345"];


}





Message Cmsglogin


{


Optional int32 ret = 1;


}





Message Cmsglogout


{


Optional int32 ret = 1;


}


The


Package represents the package name of the file in Java, and the namespace in C # representing the file, where the message represents a class,
required is required for that field, optional is optional for that field, and you can set a default value for it. Default value format: [defalut= string is "123", Integer is 123].

How to compile the proto file

java or Android use compilation method

Authentic proto can be compiled in Linux also has to provide win version of the compilation, because of the Linux compiler to configure what g++ ah, and so on a bit of trouble, before the steps are almost forgotten, it is back to win version of the build it, and net version is required in the win version of the compilation.

Authentic Google's protobuf download list please refer to:http://code.google.com/p/protobuf/downloads/list  and select the win version of the download. Decompression will get a protoc.exe file, this time you can start compiling, first in Java as an example, the compilation steps are as follows:

 
cmd Open command tool

Take my Computer for example, the exe file I put in F:protoc Directory, first CD to the directory CD F:PROTOC

once again into the directory will find that the directory has a folder, that is, the proto package named directory, will produce a Msg.java file, then this file can be used to our Java or Android project.
The last step is to download a Protobuf-java-2.3.0.jar jar package that references to your Java and Android projects, OK. You can use your protobuf. The following figure:

C # or later Windows Phone 7 compilation methods used:

The. NET version of Protobuf comes from the proto community and has two versions. A version is called Protobuf-net, official site: http://code.google.com/p/protobuf-net/Writing on the comparison with C # consistent writing. Another version is called Protobuf-csharp-sport,
Official site: http://code.google.com/p/protobuf-csharp-port/writing with Java on the use of very similar, compared to follow the original eco-style Google, so do cross-platform or choose the second version of it. Because you will find that almost the same as Java, this article is also the use of this version.



Go to the site and download the win version you want. The compilation steps are as follows:

Put your proto file in your unpacked directory with Protoc.exe, ProtoGen.exe, ProtoGen.exe.config. Other files can be deleted or backed up.
or open the command line, located in the corresponding directory, you put proto file in the directory.
Input: Protoc--descriptor_set_out=msg.protobin--include_imports Msg.proto
Msg.protobin is the Prtobobin file to generate, you can use this bin file to generate CS files
Then enter Protogen msg.protobin use the bin file to generate CS files, so you can get the CSharp version of the Msg.cs file, while using the VS inside to introduce Google.ProtocolBuffers.dll. For your convenience, you can make it a batch file with the following code:

The code is as follows Copy Code
echo on
Protoc--descriptor_set_out=msg.protobin--include_imports Msg.proto
Protogen Msg.protobin


Save it as a. bat file

use protobuf compiled file for socket connection

Android and PC

Android as a client to the PC's Java server to send data, the server to get data to parse, and print out.

Client code:

The code is as follows Copy Code



Package net.testsocket;





Import java.io.IOException;


Import Java.io.InputStream;


Import Java.net.Socket;


Import java.net.UnknownHostException;





Import socket.exception.SmsClientException;


Import socket.exception.SmsObjException;





Import Msginfo. msg.cmsg;


Import Msginfo. Msg.cmsghead;


Import Msginfo. Msg.cmsgreg;


Import android.app.Activity;


Import Android.os.Bundle;


Import Android.view.View;


Import Android.widget.Button;


Import Android.widget.TextView;





Import com.google.protobuf.InvalidProtocolBufferException;





Implementation of the Client


public class Testsocket extends activity {


Private TextView Text1;


Private Button but1;


Socket socket = NULL;





public void OnCreate (Bundle savedinstancestate) {


Super.oncreate (savedinstancestate);





Thread Desktopserverthread=new Thread (new Androidserver ());


Desktopserverthread.start ();





Setcontentview (R.layout.main);





Text1 = (TextView) Findviewbyid (R.ID.TEXT1);


BUT1 = (Button) Findviewbyid (R.ID.BUT1);





But1.setonclicklistener (New Button.onclicklistener () {


@Override


public void OnClick (View v) {





Edit1.settext ("");


LOG.E ("dddd", "Sent ID");


New Thread () {


public void Run () {


try {


Socket=new Socket ("192.168.1.102", 54321);


Socket = new Socket ("192.168.1.110", 10527);


Socket = new Socket ("192.168.1.116", 12345);


Get the object that sent the message


Smsobj smsobj = new Smsobj (socket);





Set up message headers and message bodies and store messages inside


Head


Cmsghead head = Cmsghead.newbuilder (). Setmsglen (5)


. Setmsgtype (1). SETMSGSEQ (3). Settermversion (41)


. Setmsgres (5). Settermid ("11111111"). Build ();





Body


Cmsgreg BODY = Cmsgreg.newbuilder (). Setarea (22)


. setregion. Setshop. Build ();





Msg


Cmsg msg = Cmsg.newbuilder ()


. Setmsghead (Head.tobytestring (). ToStringUtf8 ())


. Setmsgbody (Body.tobytestring (). ToStringUtf8 ())


. build ();





PrintWriter out = new PrintWriter (New BufferedWriter (


New OutputStreamWriter (Socket.getoutputstream ()),


true);


Out.println (M.tostring ());


Out.println (M.tobytestring (). ToStringUtf8 ());





Sending information to the server


Msg.writeto (Socket.getoutputstream ());


Byte[] B = Msg.tobytearray ();


Smsobj.sendmsg (b);





System.out.println ("====msg==="


+ m.tobytestring (). ToStringUtf8 ());





byte[] backbytes = smsobj.recvmsg ();


//


Receiving information from the server


InputStream input = Socket.getinputstream ();





DataInputStream datainput=new DataInputStream ();


byte[] by = smsobj.recvmsg (input);


Byte[] by=recvmsg (input);


SetText (by) (Cmsg.parsefrom);





BufferedReader br = new BufferedReader (


New InputStreamReader (Socket.getinputstream ()));


String MSTR = Br.readline ();


if (!str. Equals ("")) {


Text1.settext (str);


} else {


Text1.settext ("Data Error");


// }


Out.close ();


Br.close ();





Input.close ();


Smsobj.close ();


Socket.close ();


catch (Unknownhostexception e) {


E.printstacktrace ();


catch (IOException e) {


E.printstacktrace ();


catch (Exception e) {


System.out.println (E.tostring ());


}


// };


}.start ();





}


});





}





/**


* Receive Server information


*


* @return


* @throws smsclientexception


* @author Fisher


*/


Public byte[] Recvmsg (InputStream inpustream) throws Smsobjexception {


try {





byte len[] = new byte[1024];


int count = Inpustream.read (len);





byte[] temp = new Byte[count];


for (int i = 0; i < count; i++) {


Temp[i] = Len[i];


}


return temp;


catch (Exception localexception) {


throw new Smsobjexception ("smapobj.recvmsg () occur exception!"


+ localexception.tostring ());


}


}





/**


* Get the return value to add to the text


*


* @param g


* @throws invalidprotocolbufferexception


*/


public void SetText (Cmsg g) throws Invalidprotocolbufferexception {


Cmsghead h = cmsghead.parsefrom (G.getmsghead (). GetBytes ());


StringBuffer sb = new StringBuffer ();


if (H.hasmsglen ())


Sb.append ("==len===" + h.getmsglen () + "n");


if (H.hasmsgres ())


Sb.append ("==res===" + h.getmsgres () + "n");


if (H.hasmsgseq ())


Sb.append ("==seq===" + h.getmsgseq () + "n");


if (H.hasmsgtype ())


Sb.append ("==type===" + h.getmsgtype () + "n");


if (H.hastermid ())


Sb.append ("==termid===" + h.gettermid () + "n");


if (H.hastermversion ())


Sb.append ("==termversion===" + h.gettermversion () + "n");





Cmsgreg bo = Cmsgreg.parsefrom (G.getmsgbody (). GetBytes ());


if (Bo.hasarea ())


Sb.append ("==area==" + bo.getarea () + "n");


if (Bo.hasregion ())


Sb.append ("==region==" + bo.getregion () + "n");


if (Bo.hasshop ())


Sb.append ("==shop==" + bo.getshop () + "n");


if (Bo.hasret ())


Sb.append ("==ret==" + bo.getret () + "n");


if (Bo.hastermid ())


Sb.append ("==termid==" + bo.gettermid () + "n");





Text1.settext (Sb.tostring ());


}






Service-Side code:

The code is as follows Copy Code



Package server;





Import Java.io.DataInputStream;


Import Java.io.DataOutputStream;


Import java.io.IOException;


Import Java.io.InputStream;


Import Java.net.ServerSocket;


Import Java.net.Socket;





Import Msginfo. msg.cmsg;


Import Msginfo. Msg.cmsghead;


Import Msginfo. Msg.cmsgreg;





public class Androidserver implements Runnable {





public void Run () {


try {


System.out.println ("beign:");


ServerSocket serversocket = new ServerSocket (12345);


while (true) {


System.out.println ("Waiting to receive user connection:");


Accept client Requests


Socket client = Serversocket.accept ();





DataOutputStream DataOutputStream;


DataInputStream DataInputStream;





try {


Accept Client Information


BufferedReader in = new BufferedReader (


New InputStreamReader (Client.getinputstream ()));


String str = in.readline ();


SYSTEM.OUT.PRINTLN ("Read length:" + str.length ());


System.out.println ("read:" + str);





InputStream InputStream = Client.getinputstream ();


byte[] buffer = new byte[1024 * 4];


int temp = 0;


while (temp = inputstream.read (buffer))!=-1) {


str = new String (buffer, 0, temp);


System.out.println ("===str===" + str);





File File = new file ("Userloglogin.log");


Appendlog (file, str);





InputStream InputStream = Client.getinputstream ();





DataOutputStream = new DataOutputStream (


Client.getoutputstream ());


DataInputStream = new DataInputStream (InputStream);





Byte[] D = new BufferedReader (New InputStreamReader (


DataInputStream)). ReadLine (). GetBytes ();


byte[] Bufheader = new Byte[4];


Datainputstream.readfully (Bufheader);


int len = Bytesutil.bytes4toint (Bufheader);


System.out.println (d.length);


System.out.println (Datainputstream.readline (). toString ());


byte len[] = new byte[1024];


int count = Inputstream.read (len);





byte[] temp = new Byte[count];





for (int i = 0; i < count; i++) {





Temp[i] = Len[i];


}





Protocol body


byte[] Sendbyte = new BYTE[30];


//


Datainputstream.readfully (Sendbyte);


for (byte b:sendbyte) {


System.out.println ("" +b);


//                     }


Cmsg msg = Cmsg.parsefrom (temp);


//


//


Cmsghead head = Cmsghead.parsefrom (Msg.getmsghead ()


. GetBytes ());


System.out.println ("==len===" + Head.getmsglen ());


System.out.println ("==res===" + head.getmsgres ());


System.out.println ("==seq===" + head.getmsgseq ());


System.out.println ("==type===" + Head.getmsgtype ());


System.out.println ("==termid===" + Head.gettermid ());


System.out.println ("==termversion==="


+ head.gettermversion ());





Cmsgreg BODY = Cmsgreg.parsefrom (Msg.getmsgbody ()


. GetBytes ());


System.out.println ("==area==" + Body.getarea ());


System.out.println ("==region==" + body.getregion ());


System.out.println ("==shop==" + body.getshop ());





PrintWriter out = new PrintWriter (New BufferedWriter (


New OutputStreamWriter (Client.getoutputstream ()),


true);


Out.println ("Return" +msg.tostring ());





In.close ();


Out.close ();





Sendprotobufback (DataOutputStream);





Inputstream.close ();


Datainputstream.close ();


catch (Exception ex) {


System.out.println (Ex.getmessage ());


Ex.printstacktrace ();


finally {


Client.close ();


System.out.println ("close");


}


}


catch (IOException e) {


System.out.println (E.getmessage ());


}


}





public static void Main (string[] args) {


Thread desktopserverthread = new Thread (new Androidserver ());


Desktopserverthread.start ();


}





Private byte[] Getprotobufback () {





Head


Cmsghead head = Cmsghead.newbuilder (). Setmsglen (5)


. Setmsgtype (1). SETMSGSEQ (3). Settermversion (41)


. Setmsgres (5). Settermid ("11111111"). Build ();





Body


Cmsgreg BODY = Cmsgreg.newbuilder (). Setarea (22)


. setregion. Setshop. Build ();





Msg


Cmsg msg = Cmsg.newbuilder ()


. Setmsghead (Head.tobytestring (). ToStringUtf8 ())


. Setmsgbody (Body.tobytestring (). ToStringUtf8 ())


. build ();





return Msg.tobytearray ();


}





private void Sendprotobufback (DataOutputStream dataoutputstream) {





byte[] backbytes = Getprotobufback ();


Protocol Head


Integer len2 = backbytes.length;


First four bytes, indicating the length of the Protocol body


byte[] cmdHead2 = Bytesutil.inttobytes4 (LEN2);





try {


Dataoutputstream.write (cmdHead2, 0, cmdhead2.length);


Dataoutputstream.write (backbytes, 0, backbytes.length);


Dataoutputstream.flush ();


catch (IOException e) {


E.printstacktrace ();


}


}





}




The final result:

Client:



Service side:



the implementation code for the PROTOBUF. NET version is as follows:

The code is as follows Copy Code



Using System;


Using System.IO;


Using System.Net;


Using System.Net.Sockets;


Using System.Threading;


Using Google.protocolbuffers;


Using Msginfo;


Using System.Text;


Using System.Collections;


Using System.Collections.Generic;





Namespace Protobuf_csharp_sport


{


Class Program


{


private static ManualResetEvent Alldone = new ManualResetEvent (false);





static void Main (string[] args)


{


Beginprotocbuf ();


}





private static void Beginprotocbuf ()


{


Start the service side


TcpListener Server = new TcpListener (Ipaddress.parse ("127.0.0.1"), 12345);


Server. Start ();


Server. Beginaccepttcpclient (clientconnected, server);


Console.WriteLine ("SERVER: Waiting for data---");





Start the client


ThreadPool.QueueUserWorkItem (runclient);


Alldone.waitone ();





Console.WriteLine ("SERVER: Exit---");


Server. Stop ();


}





Service-side processing


private static void clientconnected (IAsyncResult result)


{


Try


{


TcpListener Server = (TcpListener) result. asyncstate;


using (tcpclient client = server. Endaccepttcpclient (Result))


{


using (NetworkStream stream = client. GetStream ())


{


Get


Console.WriteLine ("SERVER: Client connected, data read in---");


byte[] Myrequestbuffer = new byte[1024];





int myrequestlength = 0;


Todo


{


Myrequestlength = stream. Read (myrequestbuffer, 0, myrequestbuffer.length);


}


while (stream. dataavailable);





Cmsg msg = Cmsg.parsefrom (Myrequestbuffer.removeemptybyte (myrequestlength));





Cmsghead head = Cmsghead.parsefrom (Encoding.ASCII.GetBytes) (Msg. Msghead));


Cmsgreg BODY = Cmsgreg.parsefrom (Encoding.ASCII.GetBytes) (Msg. Msgbody));





Idictionary<google.protocolbuffers.descriptors.fielddescriptor, object> d = head. AllFields;


foreach (var item in D)


{


Console.WriteLine (item. Value.tostring ());


}





D = body. AllFields;


Console.WriteLine ("===========================================");


foreach (var item in D)


{


Console.WriteLine (item. Value.tostring ());


}





Console.WriteLine ("SERVER: Response Successful---");





Console.WriteLine ("SERVER: Close Connection---");


Stream. Close ();


}


Client. Close ();


}


}


Finally


{


Alldone.set ();


}


}





Client requests


private static void Runclient (object state)


{


Try


{


Cmsghead head = Cmsghead.createbuilder ()


. Setmsglen (5)


. Setmsgtype (1)


. SETMSGSEQ (3)


. Settermversion (4)


. Setmsgres (5)


. Settermid ("11111111")


. Build ();





Cmsgreg BODY = Cmsgreg.createbuilder ().


Setarea (22)


. Setregion (33)


. Setshop (44)


. Build ();





Cmsg msg = Cmsg.createbuilder ()


. Setmsghead (head. Tobytestring (). ToStringUtf8 ())


. Setmsgbody (body. Tobytestring (). ToStringUtf8 ())


. Build ();








Console.WriteLine ("CLIENT: Finished construction ...");





using (tcpclient client = new TcpClient ())


{


Client. Connect (New IPEndPoint (Ipaddress.parse ("192.168.1.116"), 12345);


Client. Connect (New IPEndPoint (Ipaddress.parse ("127.0.0.1"), 12345);


Console.WriteLine ("Client:socket Connection successful ...");





using (NetworkStream stream = client. GetStream ())


{


Send


Console.WriteLine ("CLIENT: Send Data ...");





Msg. WriteTo (stream);





Shut down


Stream. Close ();


}


Client. Close ();


Console.WriteLine ("CLIENT: Close ...");


}


}


catch (Exception error)


{


Console.WriteLine ("CLIENT ERROR: {0}", ERROR.) ToString ());


}


}





}//end class











public static class Extensionclass {


public static byte[] Removeemptybyte (this byte[] by,int length)


{


byte[] Returnbyte = new Byte[length];





for (int i = 0; i < length; i++)


{


Returnbyte[i] = By[i];


}


return returnbyte;





}


}




The effect of the operation:




This is OK, then you can change the Java server IP or port to the C # IP and service-side products, or vice versa. The C + + version is also available for testing. It's a cool word.

This article Protobuf realizes the Android socket communication Development course to introduce to you here!

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.