Unity3D使用TCP/IP协议,传递protocol buffer消息protobuf-net

原文:http://my.oschina.net/faint/blog/296785

第一部分 dll

1 下面大多数内容,都是使用c#编译的dll来实现的。

2 编译为dll后,要拖放到unity3d的Assets里面,才能using到。

3 有以下类似错误,就是使用了非.net 2.0编译的dll。注意项目必须是在.net 2.0版本编译的才能正常在unity3d当中使用。

Unhandled Exception: System.TypeLoadException: Could not load type ‘System.Runtime.Versioning.TargetFrameworkAttribute‘ from assembly ‘MyModel‘

4 应该不能用MonoDevelop编译下面会提到的Serializer部分(编译不出dll,会报错)。需用vs编译。

第二部分 tcp/ip

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

using System;

using System.IO;

using System.Net.Sockets;

namespace TcpConnector{

    public struct Msg {

        public int Type;

        public int Size;

        public byte[] Content;

    }

    public class Connector{

        const int HEAD_SIZE = 4;

        private TcpClient client;

        NetworkStream stream;

        public bool Connect(string ip,int port){

            try{

                client =  new TcpClient(ip,port);

                stream = client.GetStream();

                return true;

            }

            catch{

                return false;

            }

        }

        public void Disconnect(){

            stream.Close();

            client.Close();

        }

        private int readType(){

            byte[] headData = new byte[HEAD_SIZE];

            stream.Read(headData,0,headData.Length);

            int msgType = BitConverter.ToInt32(headData,0);

            return msgType;

        }

        private int readSize(){

            byte[] headData = new byte[HEAD_SIZE];

            stream.Read(headData,0,headData.Length);

            int msgSize = BitConverter.ToInt32(headData,0);

            return msgSize;

        }

        private byte[] readContent(int leghth){

            byte[] content = new byte[leghth];

            stream.Read(content,0,content.Length);

            return content;

        }

        public Msg Read(){

            Msg msg = new Msg();

            msg.Type = readType();

            msg.Size = readSize();

            if (msg.Size > 0) {

                msg.Content = readContent(msg.Size);

            }

            return msg;

        }

        public void Write(int msgType,byte[] msgContent){

            byte[] msgTypeByte = BitConverter.GetBytes(msgType);

            int msgSize = HEAD_SIZE+HEAD_SIZE+msgContent.Length;

            byte[] msgSizeByte = BitConverter.GetBytes(msgSize);

            int totalSize = HEAD_SIZE+HEAD_SIZE+msgSize;

            byte[] msgByte = new byte[totalSize];

            int index = 0;

            int i = 0;

            for (i=0;i<HEAD_SIZE;i++){ // put msg type

                if (msgTypeByte.Length>i){

                    msgByte[index] = msgTypeByte[i];

                }

                index++;

            }

            for (i=0;i<HEAD_SIZE;i++){ // put msg size

                if (msgTypeByte.Length>i){

                    msgByte[index+i] = msgSizeByte[i];

                }

                index++;

            }

            for (i=0;i<msgSize;i++){ // put msg content

                if (msgTypeByte.Length>i){

                    msgByte[index+i] = msgContent[i];

                }

                index++;

            }

            stream.Write(msgByte,0,msgByte.Length);

            stream.Flush();

        }

    }

}

主要用的是TcpClient,NetworkStream,BitConverter.

?


1

2

3

4

5

6

7

8

9

TcpClient client = new TcpClient(ip,port); // 获取与服务器连接

NetworkStream stream = client.GetStream(); // 获取连接的流

stream.Read(buf,0,lenght); // 读取至buf

stream.Write(buf,0,lenght); // 写至buf

BitConverter.GetBytes(data); // 用于将整数转为字节

BitConverter.ToInt32(data,0); // 用于将字节转为整数

stream.Flush(); // 将流中缓存发出,而不等候

stream.Close(); // 关闭流

client.Close(); // 关闭连接

第三部分 protobuf-net

FQ下载安装:http://code.google.com/p/protobuf-net/

数据结构编译成dll:

先新建解决方案,新建库,添加下载的full/unity/dll。具体代码如下:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

using System;

using ProtoBuf;

namespace CSProtoData

{

    [ProtoContract]

    public class Head

    {

        [ProtoMember(1)]

        public Int32 DataType { getset; }

        [ProtoMember(2)]

        public Int64 DataDate { getset; }

        [ProtoMember(3)]

        public byte[] DataContent { getset; }

    }

    [ProtoContract]

    public class Number

    {

        [ProtoMember(1)]

        public Int32 Index { getset; }

        [ProtoMember(2)]

        public Int64 Value { getset; }

    }

    public class Board

    {

        [ProtoMember(1)]

        public Int64 Rank { getset; }

        [ProtoMember(2)]

        public string TargetName { getset; }

        [ProtoMember(3)]

        public Int64 Number { getset; }

    }

    public class Request

    {

        [ProtoMember(1)]

        public string DataType { getset; }

        [ProtoMember(2)]

        public Int64 DataDate { getset; }

        [ProtoMember(3)]

        public Int32 Start { getset; }

        [ProtoMember(4)]

        public Int32 End { getset; }

    }

}

编译完后,生成dll下面马上用到(同时也要拖放到unity/assets下)。

第三部分 下

因为protobuf-net的序列化和反序列化用的是jit,ios不支持jit,所以需采用编译成dll的方式来解决问题:

vs中,新建命令行程序,添加protobuf-net/full/unity/dll,添加刚生成的dll,代码如下:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

using System;

using ProtoBuf;

using ProtoSerializer;

using CSProtoData;

namespace ProtoSerializer

{

    class MainClass

    {

        public static void Main(string[] args)

        {

            var model = ProtoBuf.Meta.TypeModel.Create();

            model.Add(typeof(Head), true);

            model.Add(typeof(Number), true);

            model.Add(typeof(Board), true);

            model.Add(typeof(Request), true);

            model.Compile("CSProtoSerializer""CSProtoSerializer.dll");

        }

    }

}

这里按运行后,会在目录下生成:CSProtoSerializer.dll,一样拖放到unity/assets下。

其中typeof()的,就是proto数据类型,在上半部分有定义的内容。

第四部分 unity代码

执行完以上步骤,unity/assets下应该有这么几个dll:

protobuf-net/full/unity/dll

proto的data的dll(第三部分)

data的序列化的dll(第三部分下,运行后生成的那个)

还有用于tcp连接的dll(第二部分)

那么实际在unity当中调用的代码则是:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

using UnityEngine;

using System.Collections;

using TcpConnector;

using ProtoBuf;

using CSProtoData;

using System.IO;

public class testTcp : MonoBehaviour {

    // Use this for initialization

    void Start () {

        Connector conn = new Connector();

        bool result = conn.Connect("127.0.0.1",17093);

        Debug.Log(result);

        Head head=new Head{};

        head.DataType = 2;

        head.DataDate = 201407312;

        MemoryStream memStream = new MemoryStream();

        ProtoBuf.Serializer.Serialize<CSProtoData.Head>(memStream, head);

        byte[] x = memStream.ToArray();

        conn.Write(1,x);

        conn.Write(1,x);

    }

    

    // Update is called once per frame

    void Update () {

        

    }

}

新建个script,随便挂在比如camara的组件里即可。

时间: 2024-09-30 13:09:31

Unity3D使用TCP/IP协议,传递protocol buffer消息protobuf-net的相关文章

TCP/IP协议,HTTP协议

1. 协议  a. TCP/IP总体构架概述     TCP/IP协议并不全然符合OSI的七层參考模型.传统的开放式系统互连參考模型,是一种通信协议的7层抽象的參考模型,当中每一层运行某一特定任务.该模型的目的是使各种硬件在同样的层次上相互通信.这7层是:物理层.数据链路层.网路层.传输层.话路层.表示层和应用层.而TCP/IP通讯协议採用了4层的层级结构,每一层都呼叫它的下一层所提供的网络来完毕自己的需求.这4层分别为:     i.   应用层:应用程序间沟通的层,如超文本传送协议(HTTP

OSI七层模型详解 TCP/IP协议

总结 OSI中的层 功能 TCP/IP协议族 应用层 文件传输,电子邮件,文件服务,虚拟终端 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 等等 表示层 数据格式化,代码转换,数据加密 没有协议 会话层 解除或建立与别的接点的联系 没有协议 传输层 提供端对端的接口 TCP,UDP 网络层 为数据包选择路由 IP,ICMP,OSPF,EIGRP,IGMP 数据链路层 传输有地址的帧以及错误检测功能 SLIP,CSLIP,PPP,MTU 物理层 以二进制数据形式在物理媒体上

TCP/IP协议

为什么会有TCP/IP协议 在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别.就好像圣经中上帝打乱了各地人的口音,让他们无法合作一样.计算机使用者意识到,计算机只是单兵作战并不会发挥太大的作用.只有把它们联合起来,电脑才会发挥出它最大的潜力.于是人们就想方设法的用电线把电脑连接到了一起. 但是简单的连到一起是远远不够的,就好像语言不同的两个人互相见了面,完全不能交流信息.因而他们需要定义一些共通的东西来进行交流,TCP/IP就是

七、TCP/IP协议

1.定义: TCP/IP模型也被称作DoD模型(Department of Defense Model).TCP/IP字面上代表了两个协议:TCP(传输控制协议)和IP(网际协议). TCP/IP协议不是TCP和IP这两个协议的合称,而是指因特网整个TCP/IP协议族.从协议分层模型方面来讲,TCP/IP由四个层次组成:网络接口层.网络层.传输层.应用层. TCP/IP协议并不完全符合OSI的七层参考模型,OSI(Open System Interconnect)是传统的开放式系统互连参考模型,

OSI 七层模型和 TCP/IP 协议比较

OSI (Open System Interconnection), 开放式系统互联参考模型.从下到上七层模型功能及其代表协议: 物理层(Physical) :规定了激活.维持.关闭通信端点之间的机械特性.电气特性.功能特性以及过程特性.该层为上层协议提供了一个传输数据的物理媒体.Bit,比特.典型协议代表:EIA/TIA-232, EIA/TIA-499, V.35, V.24, RJ45, Ethernet, IEEE 802.3x(以太网) 物理层, FDDI(Fiber Distribu

Android网络编程系列 一 TCP/IP协议族

在学习和使用Android网路编程时,我们接触的仅仅是上层协议和接口如Apache的httpclient或者Android自带的httpURlconnection等等.对于这些接口的底层实现我们也有必要进一步的了解,这就要我们了解网络通信层了,提到网络通信层不得不说起ISO-OSI的七层协议经典架构,如图所示: 上图的左边部分就是osi架构模型了, ISO/OSI模型,即开放式通信系统互联参考模型(Open System Interconnection Reference Model),是国际标

深入浅出--iOS的TCP/IP协议族剖析&amp;&amp;Socket

深入浅出--iOS的TCP/IP协议族剖析&&Socket 简介 该篇文章主要回顾--TCP/IP协议族中的TCP/UDP.HTTP:还有Socket.(--该文很干,酝酿了许久!你能耐心看完吗?) 我在这个文章中,列举了常见的TCP/IP族中的协议,今天主角是--传输层协议. 传输层(Transport Layer)是OSI(七层模型)中最重要.最关键的一层,它负责总体的数据传输和数据控制的一层,传输层提供端到端(应用会在网卡注册一个端口号)的交换数据的机制,检查分组编号与次序.传输层对

TCP/IP 协议详解

1.主机到网络层协议:以太网协议 2.IP协议 3.网际控制报文协议(ICMP) 4.传输控制协议(TCP) 5.用户数据报文协议(UDP) 6.流控制传输协议(SCTP) 7.地址解析协议(ARP) 联网的各个终端之间能否进行交互的软件基础是网络协议栈,目前主流的网络协议栈是TCP/IP协议栈. 1.主机到网络层协议:以太网协议 主机到网络层主要为IP协议和ARP协议提供服务.发送和接收网络数据报.本层中由于要实现跨网和跨设备的互通,有很多的实现方式,这里我们只关注以太网的实现方式. 以太网是

计算机网络 0.初识Internet与TCP/IP协议

互联网,即因特网,Internet.互联网是一个世界范围的计算机网络.连接了世界上无数的计算设备,这些计算设备为PC,基于Linux的工作站,服务器servers等等.这些设备根据其作用不同可以被称为主机host或者端系统end system. 端系统通过通信链路communication link和分组交换机packet switch连接到一起.发送数据时,发送端系统将数据分段,并为每段加上首部字节.这样的形成的信息包称为分组packet.分组到达目标端系统后,被装配成初始数据.分组交换机从它