美文网首页
socket——python和unity之间传输Json数据

socket——python和unity之间传输Json数据

作者: kindol | 来源:发表于2018-01-28 15:19 被阅读0次

    做实验室的项目,使用socket在python和unity之间传输json数据,遇到了不少坑。

    python程序之间以及C#程序之间的socket通信

    先讲讲两个python之间的socket通信,不得不赞叹python写代码简直舒服,估计以后写代码会经常拿python先试试水比较思路,有大致模型后再考虑转其他语言编码

    比较需要注意的是,在不同语言的程序之间进行socket通信,编码需要同时设置为UTF-8或者其他,否者将会出现乱码

    python程序和C#程序的socket传输json

    先码上

    import socket
    import threading
    import json
    
    sendData = {
      "infolist":
      [
        {
          "name": "fefa",
          "age": "34"
        },
        {
          "name": "hrg",
          "age": "21
        }
      ]
    }
    
    # 当新的客户端连入时会调用这个方法
    def on_new_connection(client_executor, addr):
        print('Accept new connection from %s:%s...' % addr)
    
        # 发送一个信息
        #while(True):
        client_executor.send(bytes(repr(json.dumps(sendData)).encode('utf-8')))   #发送json信息
    
        client_executor.close()
        print('Connection from %s:%s closed.' % addr)
    
    # 构建Socket实例、设置端口号  和监听队列大小
    listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    listener.bind(('127.0.0.1', 10086))
    listener.listen(5)
    print('Waiting for connect...')
    
    # 进入死循环,等待新的客户端连入。一旦有客户端连入,就分配一个线程去做专门处理。然后自己继续等待。
    while True:
        client_executor, addr = listener.accept()
        t = threading.Thread(target=on_new_connection, args=(client_executor, addr))
        t.start()
    

    通过python发送json信息,首先需要使用json.dumps将dict格式转化为str格式,但socket仅支持发送byte序列,因而还需要将str序列化,也就是repr()函数,再一个编码完成即可

    而对应于unity端的C# socket接收,使用Unity工具集的jsonUtility进行json解析

    using Assets.Scripts;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Runtime.Serialization;
    using System.Text;
    using System.Threading;
    using UnityEngine;
    
    public class getSocket : MonoBehaviour
    {
        private TextMesh text;
        private string message;
        private Socket client;
        private string host = "127.0.0.1";
        private int port = 10086;
        private byte[] messTmp;
    
        // Use this for initialization
        void Start()
        {
            text = GameObject.FindGameObjectWithTag("text").GetComponent<TextMesh>();
            messTmp = new byte[1024];
    
            // 构建一个Socket实例,并连接指定的服务端。这里需要使用IPEndPoint类(ip和端口号的封装)
            client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    
            try
            {
                client.Connect(new IPEndPoint(IPAddress.Parse(host), port));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return;
            }
    
            //client.Close();
        }
    
        Data ReadToObject(string json)
        {
            Data deserializedUser = new Data();               
            deserializedUser = (Data)JsonUtility.FromJson(json, deserializedUser.GetType());
            return deserializedUser;
        }
    
        void GetMessage()
        {
            var count = client.Receive(messTmp);
    
            if (count != 0)
            {
                Data frame = ReadToObject(Encoding.UTF8.GetString(messTmp, 1, count - 2));
                message = frame.ToString();
                Array.Clear(messTmp, 0, count);
            }
        }
    
        void FixedUpdate()
        {
            GetMessage();
            text.text = message;
        }
    
    }
    

    Data.cs

    [Serializable]
        class Data
        {
            public List<Frame> infolist;
    
            public override string ToString()
            {
                string tmp = "";
                foreach(Frame one in infolist)
                {
                    tmp += one+"\n";
                }
    
                return tmp;
            }
    
        }
    

    Frame.cs

    [Serializable]
        class Frame
        {
            public string name;
            public string age;        
    
            public override string ToString()
            {
                return "name: " + name + " age: " + age;
            }
        }
    

    unity端需要注意几点:

    1.jsonUtility存在一些局限性(这是个大坑)。
    好比如以上代码,如果python传输过来的数据直接是

    {
        "name": "fefa",
        "age": "34"
    }
    

    或者

    [
        {
            "name": "fefa",
            "age": "34"
        },
        {
            "name": "hrg",
            "age": "21"
        }
    ]
    

    并直接进行解析赋予对象,将导致解析失败

    2.对于被序列化的对象,必须加上[Serializable]

    3.经过python的json.dumps过来后的数据不可以直接在C#进行解析!如下图


    3.JPG

    注意蓝色一行,(测试用),从socket刚刚接收过来的数据,解析为str后,也就是字符串haha,里面竟然有“‘”,这里没办法解析,需要去除,否则报错,所以在传入ReadToObjec()函数里面的string是去除了“’”的字符串

    稍触皮毛,有深入会改进

    参考:

    http://blog.csdn.net/yy763496668/article/details/77875195
    https://www.jianshu.com/p/269826e9e06e
    

    相关文章

      网友评论

          本文标题:socket——python和unity之间传输Json数据

          本文链接:https://www.haomeiwen.com/subject/krxzaxtx.html