做过有网络相关游戏的人都知道protobuf,google的一套开源工具,用于发送信息的序列化和反序列化,是一个非常重要的网络工具。下面给大家介绍的是使用Protobuf用来实现信息的发送,并让信息在Java服务器上接受显示,想了解的同学可以看看。

这边提供我工程中使用的protobuf和其转换器:

http://download.csdn.net/detail/u012632851/9760880

我们做的是客户端,首先说Unity方面的导入吧。

Unity直接导入cs的源代码,而不是dll文件,其实差不多。我的资源的话直接把根目录下的protobuf-net拖入Unity工程就行了,不过网上自己去下载最新版本的同学可能会碰到两个问题:

1.如上图,说使用了不安全的代码,这个时候只要在Assets目录下新建一个smcs.rsp的文件,内容是-unsafe,保存后重启Unity就能通过运行了;

2.MetaType中有无法解析的符号,这个去vs中看的话,它会提示你我们用的C#版本是4,而语法的版本是6,这个无法解决。我最后是直接替换老版本的MetaType脚本进去,其他的还是新的,然后就没有任何错误了。

环境搭建完成之后接下来就是制作与服务器通信的类了,直接看例子,以下是通信协议:

文件名称并非是无关紧要的,common会转换成C#中的namespace,而message后面的mymessage会转换成具体的类。

使用的时候就应该这样使用:

using common;

mymessage myMsg = new mymessage();

这里有个坑,大家也看到了java_package的一行,没错,在java的转换中文件名就是个类,而mymessage是个内部类,所以使用java_package指定包名,大家可以试试不写的结果,我查了一下,没找到导入默认包的方法。

使用的时候如此使用:

import protobuf.Common;

Common.mymessage.Builder msg2b = Common.mymessage.newBuilder();

Common.mymessage msg2 = msg2b.build();

byte[] b = msg2.toByteArray();

现在这些代码是无法使用的,接下来就是转换器,把上面协议的内容转换成C#、Java代码,可以参考我资源中message文件夹下的makeProtobuf.bat文件。

贴出来给大家看看吧,没什么好说的,就是使用相应的exe应用程序进行转换:

@echo off

set tool=..\protobuf-net\net

rem ============================================

rem Support

set proto=common.proto

%tool%\protogen.exe -i:%proto% -o:%proto%.cs -q

set proto=message.proto

%tool%\protogen.exe -i:%proto% -o:%proto%.cs -q

..\protobuf-java\protoc.exe -I=. --java_out=. common.proto

..\protobuf-java\protoc.exe -I=. --java_out=. message.proto

pause

没有问题的话就直接输出请继续字样的提示。

运行之后会出现如下的文件:

protobuf中的是java的,而两个cs文件是Unity的。

Unity是最方便的,这两个文件你随便放哪都行,当然工程中要导入protobuf的前期下哈。

接下来是发送协议数据的代码:

using UnityEngine;

using System.IO;

using ProtoBuf;

using common;

public class ProtobufTest : MonoBehaviour {

SocketSink socketSink;

// Use this for initialization

void Start () {

socketSink = SocketSink.getInstance();

}

float dTime = 0f;

float maxDTime = 1f;

// Update is called once per frame

void Update () {

// 如果服务器没有连接

if(!socketSink.isConnected)

{

dTime = Time.deltaTime;

if(dTime > maxDTime)

{

dTime = 0f;

socketSink.init(); //每隔一秒重连一次服务器

}

}

}

private void OnGUI()

{

// 连上服务器之后,可以发送消息

if(socketSink.isConnected)

{

if(GUILayout.Button("发送"))

{

//socketSink.sendDataToServer("hello#");

// 建立一个消息

mymessage myMsg = new mymessage();

myMsg.myid = 1;

myMsg.message = "haha";

using (MemoryStream ms = new MemoryStream())

{

// 进行序列化

Serializer.Serialize(ms, myMsg);

byte[] data = new byte[ms.Length];

ms.Position = 0;

ms.Read(data, 0, data.Length); //将序列化完成的数据方法byte数组中

// 向服务器发送

socketSink.sendProtobufDataToServer(data);

}

}

}

}

}

一个简单的事例,就是按下屏幕的按钮就会发送数据。额,SocketSink是客户端建Socket底层的代码,在这就不提供给大家了,如果有问题可以评论区里提问,实在有需要的话,我可以考虑提供一下(不过估计没什么人看,哈哈)。

这样Unity上的开发就搞定了。

接下来是服务器,Eclipse上的开发是蛋疼的,感觉大学里学的java都白学了。。。

安装完成后,新建个java项目输出Helloworld看看有没有问题,嗯对,普通项目就可以了。

首先将资源中的protobuf-java-2.5.0.jar导入工程,再将之前协议转换出来的Java代码导入,最后的目录结构是这样:

这个完成之后,只要开一下Socket服务器监听,然后接受Unity发送来的数据就可以了。

下面是Java代码:

public class SimpleServer {

public static void main(String[] args)

{

try{

// 服务器监听的总类,只存在一个,端口是5200

ServerSocket serverSocket=new ServerSocket(5200);

Socket socket=null;

while(true){

// 获取Unity客户端的连接,每有一个客户端,对应一个Socket

socket=serverSocket.accept();

// 开启监听线程

SimpleServerThread serverThread=new SimpleServerThread(socket);

serverThread.start();

InetAddress address=socket.getInetAddress();

System.out.println("来了一个客户端:" address.getHostAddress());

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

上面开启了一个监听,具体处理交给了SimpleServerThread,下面是具体脚本:

public class SimpleServerThread extends Thread {

Socket socket = null; // 记录客户端对应的Socket

SimpleServerThread(Socket socket)

{

this.socket = socket;

}

public void run()

{

System.out.println("读取线程启动");

//循环读取数据

while(true)

{

try{

System.out.println("读取中。。。");

// StringBuilder sb = new StringBuilder();

byte[] bs = new byte[1024]; //存放消息的byte数组

InputStream is = socket.getInputStream(); //socket产生的一个读入流

int len = -1;

// 读入

len = is.read(bs);

// 转换成对应长度的数组,这里绝对是不能这么写的,不过具体处理方法暂时没想到,以后看看会不会完善一下,嘛,毕竟这是服务端的事情

byte[] mybs = new byte[len];

for(int i=0 ; i < mybs.length ; i)

{

mybs[i] = bs[i];

}

// 将获取到的数据转换成相应的类

Common.mymessage msg = Common.mymessage.parseFrom(mybs);

int id = msg.getMyid();

String m = msg.getMessage();

// 打印

System.out.println(id ":" m);

}

catch(IOException e)

{

e.printStackTrace();

}

}

}

}

这样Unity中点击发送,Eclipse里应该能接受到信息了。最终效果再来个图:

这篇博文我弄了我两天,主要找资源、搞Java的时候费了很长时间,最后总结一句话Java真NM蛋疼,哈哈。

国内的文章就是实用性高,高手看了嗤之以鼻,新手看了如获至宝,讲真的我觉得我还挺适合这样的实战学习的,不喜欢光搞理论。

希望能快点成长到嗤之以鼻的阶段。

来自:http://blog.csdn.net/u012632851/article/details/56489777

java 游戏 protobuf,Unity 3D Protobuf的使用 信息的简单发送 并在Java服务器上接受显示...相关推荐

  1. 跨平台次世代游戏引擎Unity 3D

    1.Unity简介 Unity是一款标准的商业游戏引擎,而商业引擎的主要特点有收费.封闭源码和功能强大. 关于收费情况,Unity的使用费用非常昂贵,最便宜的普通版许可证也需要400美元,加强版本为1 ...

  2. java游戏管理器 闪退_手游频繁崩溃”闪退”? 从程序上找原因

    文 / 网易 Tjay(QA) 作为玩家,当游戏crash的时候是什么心情,如果这个游戏玩起来还不错的话,那我可能还会打开第二次,如果这个游戏一般的话我可能直接怒删了.当多次出现闪退crash的时候, ...

  3. 找一个Java游戏里面有九尾狐_Javase中多态polymorphic的简单介绍

    -------------多态----------------- (1)面向对象三大核心思想: 1.封装 2.继承 3.多态 (2)多态定义:父类的引用指向子类的对象. (3)引用指的是父类声明的一个 ...

  4. java客户端连接请求发不出去_java – Spring:客户端发送的请求在语法上不正确()...

    嗨,我在重定向期间收到下一个错误: The request sent by the client was syntactically incorrect 浏览器显示的URL是:localhost:80 ...

  5. java pacs上传服务_有没有办法将DICOM数据发送到远程PACS服务器上的特定目录?

    我得到了SCU和SCP之间的DICOM服务器和图像通信的诀窍.我正在使用一个ClearCanas PACS服务器,并且可以访问webgui.使用以下代码,我可以将DICOM dt从SCU(我的计算机) ...

  6. 小白学习Unity 3D做经典游戏坦克大战日常

    老师 | Trigger 学习者 |小白 出品 | Siki 学院 Hello,小伙伴们.接下来小白跟Trigger老师做一款2D游戏坦克大战.从素材.代码到场景和UI的游戏开发.小白把日常遇到的问题 ...

  7. 聊聊在博客园写博客的这两年《Unity 3D脚本编程:使用C#语言开发跨平台游戏》正式出版...

    版本状态: 2016.9 第一次印刷 (2016.11 输出到台湾) 2017.1 第二次印刷 2017.5 第三次印刷 2017.5 电子书上线:Unity 3D脚本编程--使用C#语言开发跨平台游 ...

  8. Unity 3D 创建简单的几何模型 || Unity 3D Assets 游戏资源目录管理

    Unity 3D 创建简单的几何模型 Unity 3D 是一个强大的游戏开发引擎.在游戏开发中使用的模型常常是从外部导入的,Unity 3D 为了方便游戏开发者快速创建模型,提供了一些简单的几何模型, ...

  9. 为什么要选择 Unity 3D来开发游戏?

    选择合适的游戏引擎对于移动游戏开发项目的成功至关重要.功能丰富的 Unity 3D 引擎有助于针对跨多个设备兼容的不同平台进行游戏开发.游戏引擎具有许多资源,例如即时资产.IDE.在线社区帮助.免费教 ...

最新文章

  1. Amazon Redshift数据库
  2. composer 路径_深入学习Composer原理(三)
  3. web项目使用配置web.xml实现重定向
  4. 明日决战!TI8冠军OG与OpenAI人机大战现场探营
  5. 解决Android编译so库出错问题
  6. 学会使用Trace和Debug
  7. GPU cuda驱动安装
  8. 矩阵分解(LU分解)C语言实现
  9. 数据结构 第2版 第二版 陈越_高中数学选学---人教A版选修2-1第二章第二节椭圆...
  10. Win32 API概论
  11. Spark总结之RDD(四)
  12. 2016..8.25 切题总结
  13. Python:实现费马检测算法(附完整源码)
  14. Hadoop安全认证(2)
  15. 程序员必备画图技能之——流程图
  16. 学习笔记1—元胞自动机(CA)模型①
  17. 枫林红叶随身落, 遍地花海迹中寻。 独贪长不愿醒, 回首百年烟云过。
  18. 声学仿真分析工具Acoustics 在Workbench中这样学
  19. Get图谱 50个技能领域一键直达
  20. 《超高精度机械设计基础》——第一章 介绍 1.1什么是超高精度

热门文章

  1. 【Matlab】如何自定义无输入和无输出的函数?
  2. 主引导扇区(MBR),分区表(DPT)及活动分区(DBR)
  3. 空间分辨率、频谱分辨率、辐射计量分辨率、时间分辨率。
  4. 【C++】多线程同步
  5. 生物工程毕业的他,如何成为年薪超40w的Java程序员
  6. 可视化小目标--如何提升数据可视化的表现效果
  7. 你手机里有哪些堪称神器的 App?
  8. 今日头条 爬虫 java_Java爬虫实践:Jsoup+HttpUnit爬取今日头条、网易、搜狐、凤凰新闻...
  9. Oracle+Sql Server相关查询语句
  10. 显示器点距 测试软件,显示器各尺寸点距一览