1、下载安装Protocol Buffer
>需要下载文件:protobuf-2.5.0.tar.gz(也可以直接下载
protobuf-java-
2.5.0
.jar;这里通过maven生成
);protoc-2.5.0-win32.zip(windows平台需要)。
>解压
protobuf-2.5.0.tar.gz文件,存放在
D:\java\protobuf-2.5.0目录下
>解压
protoc-2.5.0-win32.zip,得到
protoc.exe文件;为了方便使用这里把protoc.exe文件复制到C:\Windows\System32目录下。为了通过maven编译得到jar文件,还需要把
protoc.exe复制到
D:\java\protobuf-2.5.0\src\目录下。
>打开win终端(运行->cmd),cd
D:\java\protobuf-2.5.0\java,mvn package。然后在
D:\java\protobuf-2.5.0\java\target\目录下生成
protobuf-java-2.5.0.jar文件(用于java工程,也可以通过maven获得)。
---------------------------到此安装完成。
2、编写Protobuf 的proto文件,保存到e:\workPlace\protobuf\目录下
。
>简单消息(SimpleMsg.proto)
package protobuf;
option java_package = "com.test.pr.protobuf";
option java_outer_classname = "SimpleMessage";
message Message{
required int32 id=1;
required string key=2;
required string content=3;
}
>嵌套消息(CarInfoMsg.proto)
option java_package = "com.umpay.pr.protobuf";option java_outer_classname = "CarInfos";message Car{enum CarModel{BENZ = 0;VOLKSWAGEN =1;FORD = 2;CHEVROLET = 3;TOYOTA = 4;Peugeot = 5;}enum Sex{FEMALE = 0;MALE = 1;}message CarOwner{required string name=1;required Sex sex = 2 [default = MALE];required int32 age=3;required float height=4;}message CarInfo{required string carNumber=11;required string brand=12;required string color=13;required CarModel model = 14 [default=FORD];required int64 price=15;required CarOwner owner=16;}}
3、生成Java代码
运行命令:
protoc.exe --java_out=./ ./
CarInfoMsg.proto,会在
e:\workPlace\protobuf\目录下生成com这样的目录,找到里面的
CarInfos.java文件。
4、Netty服务端(ProtobufNettyServer.java
)
/**
* desc:Htty服务端
*/
public class ProtobufNettyServer {
public static void main(String[] args) {
ServerBootstrap serverBootstrap = new ServerBootstrap( new NioServerSocketChannelFactory(
Executors.newSingleThreadExecutor(), Executors.newSingleThreadExecutor()));
serverBootstrap.setPipelineFactory( new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast( "protobufDecoder", new ProtobufVarint32FrameDecoder()); //netty自带的解码器
pipeline.addLast( "protobufEncoder", new ProtobufEncoder()); //netty自带的编码器
pipeline.addLast( "handler", new ProtobufServerHandler()); //服务handler
return pipeline;
}
});
serverBootstrap.bind( new InetSocketAddress( "0.0.0.0", 8080));
}
}
/**
* desc:服务handler
*/
class ProtobufServerHandler extends SimpleChannelHandler{
/*
* desc:
* (non-Javadoc)
* @see org.jboss.netty.channel.SimpleChannelHandler#channelConnected(org.jboss.netty.channel.ChannelHandlerContext, org.jboss.netty.channel.ChannelStateEvent)
*/
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
CarInfo o = carInfosTrans();
System.out.println( "输出~~" + o.getClass());
ChannelFuture future = e.getChannel().write(o);
future.addListener(ChannelFutureListener.CLOSE);
}
/*
* desc:
* (non-Javadoc)
* @see org.jboss.netty.channel.SimpleChannelHandler#exceptionCaught(org.jboss.netty.channel.ChannelHandlerContext, org.jboss.netty.channel.ExceptionEvent)
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
// super.exceptionCaught(ctx, e);
System.err.println( "Unexpected exception from downstream." + e.getCause());
e.getChannel().close();
}
private CarInfo carInfosTrans(){
CarOwner.Builder owner = CarOwner.newBuilder();
owner.setAge( 18);
owner.setHeight( 170);
owner.setName( "jimmy");
owner.setSex(Sex.FEMALE);
CarInfo.Builder carInfo = CarInfo.newBuilder();
carInfo.setBrand( "大众");
carInfo.setCarNumber( "粤A 88888");
carInfo.setColor( "red");
carInfo.setModel(CarModel.VOLKSWAGEN);
carInfo.setPrice( 1000);
carInfo.setOwner(owner);
CarInfo carInfoReq = carInfo.build();
// long size = carInfoReq.getSerializedSize();
// byte[] buf = carInfoReq.toByteArray();
return carInfoReq;
}
}
5、客户端代码(
ProtobufSocketClient.java
)
/**
* desc:
* @version V1.0
*/
public class ProtobufSocketClient {
public static void main(String[] args) {
try {
Socket socket = new Socket( "127.0.0.1", 8080);
InputStream in = socket.getInputStream();
CarInfo recCarInfo = CarInfo.parseFrom(in);
System.out.println(recCarInfo.getBrand());
System.out.println(recCarInfo.getCarNumber());
in.close();
socket.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客户端输出=====
大众
粤A 88888