zoukankan      html  css  js  c++  java
  • Cocos2d-x游戏开发_客户端与服务器的交互(2)使用protocol buffer

    1.关于protocol buffer的使用和简介可以参考以下3篇博客

    (1)语言规范 http://www.cnblogs.com/stephen-liu74/archive/2013/01/02/2841485.html

    (2)c++实例 http://www.cnblogs.com/stephen-liu74/archive/2013/01/04/2842533.html

    (2)java实例 http://www.cnblogs.com/stephen-liu74/archive/2013/01/06/2842972.html

    2.protocol buffer的下载以及安装

    (1)在VS环境中(C++)

      一、把protocol-2.4.1.zip下载下来,解压后进入vsprojects目录,运行libprotobuf.vcproj,生成其中的四个项目

      二、生成完之后,把protocol目录下的Debug/release目录添加到环境变量里面。

      三、利用protoc.exe 将一个proto文件转换成cpp文件代码(详情见1.的博客介绍)

      四、把生成的代码导入项目,并且配置项目的属性,

      1)右键项目-》属性-》C/C++ -》常规,设置附加包含目录,改成所下数据包的src目录。

      2)属性-》链接器-》常规,设置附加包含目录,改成vsprojects目录下编译后的release目录。 

      3)定位到属性-》输入-》附加依赖项,添加libprotobuf.lib libprotoc.lib

     

    (2)在eclipse环境中(Java)

       一、利用protoc.exe 将一个proto文件转换成java文件代码(详情见1.的博客介绍)

      二、在项目中导入生成的文件

      三、下载protocol-2.4.1.jar,导入项目

     

    3.对cocos2dx客户端和mina服务器的修改

      1)cocos2dx发送:由于protocol提供将message的语言对象(貌似很难理解,请看完上面3篇博客)转换成字符数组,所以发送不需要改动。

    	LoginReqMessage loginMsg;
    	loginMsg.set_acctid(20);
    	loginMsg.set_passwd("Hello World");
    	int length = loginMsg.ByteSize();
    	char* buf = new char[length];
    	loginMsg.SerializePartialToArray(buf,length);
    	CCLog("length = %d",length);
    	::send(HSocket::socketHandle,buf,length,0);
    

      

      2)mina的接受:

      这里我发现了一篇很好的博客,是有关于mina结合protocol buf 的:http://blog.csdn.net/mrliu20082009/article/details/6977746

       a.主要的修改是mina的过滤器改成StreamWriteFilter。这是因为protocol buf良好的支持字节流,所有要使用此过滤器

       b.mina的handler改成用IoBuffer来缓冲

         IoBuffer buffer = (IoBuffer)message;
        	ByteBuffer bf = buffer.buf();
        	byte[] buf = new byte[bf.limit()];
        	bf.get(buf);
        	LoginReqMessage loginReq = LoginReqMessage.parseFrom(buf);
        	System.out.println(loginReq.getAcctID());
    

     

       3)mina的返回

      不能直接write字节数组,必须使用IoBuffer对象(因为是字节流),flip方式是必须调用的,否则客户端无法获得数据。

       LoginReqMessage.Builder loginReqBuilder = LoginReqMessage.newBuilder();
     		loginReqBuilder.setAcctID(20);
     		loginReqBuilder.setPasswd("hello fuck world");
     		LoginReqMessage backMessage = loginReqBuilder.build();
     		
     		int length = loginReq.getSerializedSize();
     		System.out.println("Size=" + length);
     		System.out.println(loginReq.toString());
     		byte[] bb = backMessage.toByteArray();
     		IoBuffer resp = IoBuffer.allocate(bb.length);
     		resp.put(bb,0,bb.length);
     		resp.flip();
     		session.write(resp);
     		System.out.println("已经返回信息了");

       

     

      4)cocos2dx的接受

      因为BSD socket中的recv必须知道返回的字符数组的长度,所以我先定义了一个很大的数组,并且全用''初始化。

      之后在转换成message对象的时候,直接用strlen函数就可以准确的获取长度了。

    	char back[100];
    	memset(back,100,'');
    	::recv(HSocket::socketHandle,back,100,0);
    	LoginReqMessage loginMsg2;
    	loginMsg2.ParseFromArray(back,strlen(back));
    	CCLOG("id=%I64d",loginMsg2.acctid());
    	CCLOG("backMsg=%s",back);
    

      

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 洗牌
    判断一个窗口是否被挂起(发WM_NULL消息,或者调用IsHungAppWindow API进行测试)
    线程天敌TerminateThread与SuspendThread
    Visual C++ 异常(Exception)常见问题 (原文标题:A Visual C++ Exception FAQ)
    阻止屏保运行、显示器和系统待机(使用SystemParametersInfo和SetThreadExecutionState两种办法)
    C语言编译全过程
    MSbuild 教程
    Mac OS X下环境搭建 Sublime Text 2 环境变量配置 开发工具配置Golang (Go语言)
    grunt实用总结
    DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?
  • 原文地址:https://www.cnblogs.com/hezijian/p/3758091.html
Copyright © 2011-2022 走看看