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!