C# protobuf客户端连接JavaNetty+protobuf服务器(一)

网络上下载protoc 和 protogen 工具,我的百度云盘地址,主要用到红框内两个。
http://pan.baidu.com/s/1bpwFcmF
C# protobuf客户端连接JavaNetty+protobuf服务器(一)_第1张图片
(1)创建一个protoc.bat (名字随意起的),添加以下内容。我的protoc.exe和protogen.exe已经添加到环境变量里面了。
echo on
protoc.exe --descriptor_set_out=userLogin.protobin --include_imports userLogin.proto
protogen.exe userLogin.protobin

(2)创建文件 userLogin.proto(名字随意起的),添加以下内容
package ProtoTest;  
message TestInfo{  
 required string test = 1;  
 optional int32 num = 2;  
}  
  
message Msg{  
 required int32 id = 1;  
 optional TestInfo msg = 2;  
 optional string str = 3 [default="Test String"];  
} 
运行bat脚本,可以看到如下结构。

(3)编译Java+protobuf协议文件
创建脚本 protoJava.bat (名字随意起的),添加以下内容。
echo on
protoc.exe --java_out=./ userLogin.proto
注意userLogin.proto 前边与斜杠有空格。
运行后生成 ProtoTest/UsrLogin.java文件
C# protobuf客户端连接JavaNetty+protobuf服务器(一)_第2张图片
(4)eclipse新建maven项目,引入 编译后的Java文件
放入合适的包,修改对应的类名, 修改成自己本地对应的包名。
C# protobuf客户端连接JavaNetty+protobuf服务器(一)_第3张图片
maven项目中引入合适的2.5.0版本的protobuf-Java依赖

(5)vs2012新建C#项目,控制台应用程序 C# protobuf客户端连接JavaNetty+protobuf服务器(一)_第4张图片
(6)添加userLogin.cs文件,引入 Google.ProtocolBuffers.dll,从云盘中protoc文件夹中可以找到到。
C# protobuf客户端连接JavaNetty+protobuf服务器(一)_第5张图片 C# protobuf客户端连接JavaNetty+protobuf服务器(一)_第6张图片
(7)修改UserLogin错误为,这个可能是个bug,我还不知道原因,但是仿照别的文件做了正确修改。
C# protobuf客户端连接JavaNetty+protobuf服务器(一)_第7张图片
(8)修改C#的program.cs文件,作为socket客户端。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using Google.ProtocolBuffers;

//参考http://www.itstack.org/?post=17
namespace ProtoBufTest01
{
    class Program
    {
        static void Main(string[] args)
        {
            //设定服务器IP地址  
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                clientSocket.Connect(new IPEndPoint(ip, 7397)); //配置服务器IP与端口  
                Console.WriteLine("连接服务器成功");
            }
            catch (Exception ex)
            {
                Console.WriteLine("连接服务器失败,请按回车键退出!" + ex);
                return;
            }

            //通过clientSocket接收数据 [暂不使用]
            //int receiveLength = clientSocket.Receive(result);
            //Console.WriteLine("接收服务器消息:{0}", receiveLength);

            //通过 clientSocket 发送数据  
            for (int i = 0; i < 5; i++)
            {
                try
                {
                    //构建数据

                    //封装protobuf empBean实例化
                    ProtoTest.TestInfo.Builder empBeanBuilder = ProtoTest.TestInfo.CreateBuilder();

                    empBeanBuilder.SetTest("QQ号码");
                    empBeanBuilder.SetNum(1422020);

                    //建立Bean
                    ProtoTest.TestInfo SendEmpBean = empBeanBuilder.Build();

                    //发送数据

                    //转为byte字节
                    byte[] buf = SendEmpBean.ToByteArray();
                    //通过socket发送
                    clientSocket.Send(buf);
                    //休眠500毫秒
                    Thread.Sleep(500);


                    Console.WriteLine("向服务器发送消息");
                }
                catch (Exception ex)
                {
                    break;
                }
            }
            Console.WriteLine("发送完毕,按回车键退出");
            Console.ReadLine();

        }
    }
}
(9)添加Java服务端,netty框架
maven项目 pom.xml中添加依赖

	io.netty
	netty-all
	4.1.14.Final

如图:共新增三个Java文件。
C# protobuf客户端连接JavaNetty+protobuf服务器(一)_第8张图片
package protobuf.userLogin;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class HttpServer {
	private static Log log = LogFactory.getLog(HttpServer.class);

	public static void main(String[] args) throws Exception {
		HttpServer server = new HttpServer();
		log.info("服务已启动...");
		server.start(7397);
	}

	public void start(int port) throws Exception {
		// 配置服务端的NIO线程组
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		try {
			ServerBootstrap b = new ServerBootstrap();
			b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer() {
				@Override
				public void initChannel(SocketChannel ch) throws Exception {
					ch.pipeline().addLast(new ServerHandler());
				}
			}).option(ChannelOption.SO_BACKLOG, 128) // 最大客户端连接数为128
					.childOption(ChannelOption.SO_KEEPALIVE, true);
			// 绑定端口,同步等待成功
			ChannelFuture f = b.bind(port).sync();
			// 等待服务端监听端口关闭
			f.channel().closeFuture().sync();
		} finally {
			// 优雅退出,释放线程池资源
			workerGroup.shutdownGracefully();
			bossGroup.shutdownGracefully();
		}
	}
}

package protobuf.userLogin;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class ServerHandler extends ChannelInboundHandlerAdapter {

	private static Log log = LogFactory.getLog(ServerHandler.class);

	@Override
	public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
		super.handlerAdded(ctx);
		System.out.println(ctx.channel().id() + "进来了");
	}

	@Override
	public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
		super.handlerRemoved(ctx);
		System.out.println(ctx.channel().id() + "离开了");
	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		System.out.println("ServerHandler ========================= ");
		ByteBuf buf = (ByteBuf) msg;
		byte[] req = new byte[buf.readableBytes()];
		buf.readBytes(req);
		UserLoginDoData.doData(req);
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		ctx.flush();
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		// TODO Auto-generated method stub
		ctx.close();
	}
}

package protobuf.userLogin;

public class UserLoginDoData {

	public static void doData(byte[] result) throws Exception{
		UserLogin.TestInfo msg = UserLogin.TestInfo.parseFrom(result);
		System.out.println("number == " + msg.getNum() + " test == " + msg.getTest());
	}
}

(10)测试运行,可以看到客户端窗口发送了5条信息,服务端收到5条信息。大功告成。
C# protobuf客户端连接JavaNetty+protobuf服务器(一)_第9张图片

客户端链接服务端告一段落,服务端返回客户端可以自行测试。

你可能感兴趣的:(Unity3D开发)