原文: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的组件里即可。

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

  1. RTSP RTSP(Real Time Streaming Protocol),RFC2326,实时流传输协议,是TCP/IP协议体系中的一个应用层协议

    RTSP 编辑 RTSP(Real Time Streaming Protocol),RFC2326,实时流传输协议,是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学.网景和RealNetwo ...

  2. 门面模式的典型应用 Socket 和 Http(post,get)、TCP/IP 协议的关系总结

    门面模式的一个典型应用:Socket 套接字(Socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元.它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息: 连接使用的 ...

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

      总结 OSI中的层 功能 TCP/IP协议族 应用层 文件传输,电子邮件,文件服务,虚拟终端 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 等等 表示层 数据格式化,代码转 ...

  4. TCP/IP协议(二)tcp/ip基础知识

    今天凌晨时候看书,突然想到一个问题:怎样做到持续学习?然后得出这样一个结论:放弃不必要的社交,控制欲望,克服懒惰... 然后又有了新的问题:学习效率时高时低,状态不好怎么解决?这也是我最近在思考的问题 ...

  5. HTTP协议—— 简单认识TCP/IP协议

    大学没读计算机专业,所以很多的专业知识都不知道.既然已经从事了IT这个行业,就势必要去了解下网络底层,虽然实际工作中这些东西用不到.高楼大厦,起于平川.不积跬步,无以至千里,不积小流,无以成江海.我现 ...

  6. iOS的TCP/IP协议族剖析&&Socket

    原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0 简介 该篇文章主要回顾--TCP/IP协议族中的TCP/UDP.HTTP:还有S ...

  7. TCP/IP协议基础(转)

    转自 http://www.chinaunix.net 作者:Bernardus160  发表于:2003-12-03 17:33:15 TCP/IP协议基础 -------------------- ...

  8. TCP/IP Four Layer Protocol Format Learning

    相关学习资料 tcp-ip详解卷1:协议.pdf 目录 . 引言 . 应用层 . 传输层 . 网络层 0. 引言 协议中的网络字节序问题 在学习协议格式之前,有一点必须明白,否则我们在观察抓包数据的时 ...

  9. TCP/IP协议 HTTP协议

    TCP/IP协议 OSI传统的7层参考模型:物理层,数据链路层,网络层,传输层,话路层,表示层和应用层.而TCP/IP协议并不完全符合这7层参考模型,它只采用了其中的应用层,传输层,网络层和数据链路层 ...

随机推荐

  1. Tkinter 小应用

    import tkinter as tk class APP: def __init__(self,master): frame = tk.Frame(master) frame.pack(side ...

  2. selenium java 读取xml (数据驱动)

    selenium 数据驱动 (xml解析) getElementByTagName()可以通过标签名获取某个标签.它所获取的对象是以数组形式存放.如“caption”和“item”标签在info.xm ...

  3. MYSQL 的异常CRASH事件处理

    检查问题的过程****************************************************************************************** ps ...

  4. (十三)MySQL主从复制

    (1)工作原理 (2)主从实现 1) 环境介绍 cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core) MySQL版本:5.7 mys ...

  5. python操作数据库的几种方式

    参照python 操作mysql python-mysqldb : http://www.cnblogs.com/wupeiqi/articles/5095821.html (python3 不支持) ...

  6. CodeForces 669C

    链接:http://codeforces.com/problemset/problem/669/C http://www.cnblogs.com/Ash-ly/p/5443155.html 题意: 给 ...

  7. Codeforces #436 Div2 E

    #436 Div2 E 题意 某人的房子着火了,现在有 \(n\) 件物品待抢救,每件物品有抢救需要的时间和自身的价值,以及过多长时间物品会损坏.问最多一共可以抢救价值多少的物品? 分析 看数据就知道 ...

  8. Linux命令之file

    file [选项] [文件名] 确认文件类型 (1).常用选项 magic file指的是哪些具有特殊文件格式的文件 -b,--brief 不列出文件名称 -c,--checking-printout ...

  9. ( 转 ) Mysql group_concat 的反向应用实现(Mysql列转行)

    用过Mysql的都知道她有一个很好的实现行转列功能的函数group_concat函数,非常方便 点击(此处)折叠或打开 SELECT * FROM group_test; SELECT id, GRO ...

  10. 【单调队列】【动态规划】bzoj3831 [Poi2014]Little Bird

    f(i)=min{f(j)+(D(j)<=D(i))} (max(1,i-k)<=j<=i) 有两个变量,很难用单调队列,但是(引用): 如果fi<fj,i一定比j优秀.因为如 ...