`

JSON和byte[]

阅读更多

JsonAjax中已得到广泛的应用。相比XML,它有如下的优点:

 

1. 数据格式比较简单, 易于读写, 格式都是压缩的, 占用带宽小;

2. 易于解析这种语言, 客户端Javascript可以简单的通过eval()进行JSON数据的读取;

3. 支持多种语言, 包括Actionscript, C, C#, ColdFusion, Java, Javascript, Perl, PHP, Python, Ruby等语言服务器端语言, 便于服务器端的解析;

4. PHP世界, 已经有PHP-JSONJSON-PHP出现了, 便于PHP序列化后的程序直接调用. PHP服务器端的对象、数组等能够直接生JSON格式, 便于客户端的访问提取。

 

         除了BS模式,CS模式自然也可以使用JSON的格式。毕竟,我们可以简单的将其视为一个hashmap。那么,与一般的传送byte[]方式比较,JSON的优劣又体现在哪里?

带宽算劣势么?直接的JSON文本显然比byte[]占用更多空间,但JSON的格式在传送时候是压缩的,会不会有改善?

解析。JSON对多种语言提供了支持,便于解析。而pythonpackunpack风格,需要我们在各种语言中自行构建代码来支持。

 

		String rule = "4'int'smallendian'time,1'int'smallendian'package_type,1'int'smallendian'msgType,6'string'bigendian'srcMAC,"
			    +"4'int'smallendian'nodeID,4'string'bigendian'nodeIP,4'string'bigendian'srcIP,"
			    +"4'int'smallendian'srcPort,1'int'smallendian'srcIDlen,-1'string'bigendian'srcID,"
				+ "6'string'bigendian'destMAC,4'string'bigendian'destIP,4'int'smallendian'destPort,"
				+ "1'byte'smallendian'languageFlag,2'int'smallendian'contentlen,-1'string'bigendian'msgcontent";

 

 

这是一个javapythonstruct.unpack的模拟。当然,经过改良,我们可以相信其可以具有更好的可读性。类似如下的形式:

 

         String rule = "4!i1!i1!i…"

 

         至少在基本类型的处理上,我认为此形式可以很好的表达CS两端通信的接口。视此rule,则通信规则已了然于心。

         需要注意的地方在与‘变长’和‘复杂类型’。

         当传递一个变长字符串。可能需要如下的结构:

 

Len+Body

 

这样让我们的rule写起来就会费事。又如传递一个未知sizeList,也是一个难处理的任务。

 

         下面有一个简单的例子。Server端用python接收数据,以unpack方式接收数据,并以MysqlDB插入Mysql数据库;Client端用Erlang发送数据,以list_to_binary发送数据。

'''
Created on 2009-3-18

@author: Administrator
'''
from twisted.internet import protocol, reactor
from time import ctime
import struct
import MySQLdb

PORT = 9090

class TSServProtocol(protocol.Protocol):
    
    '''Data1 = [<<1:32/little, 1, 10>>, "srcmac", <<1234:32/little, 1, 2, 3, 4, 1, 2, 3, 4, 1234:32/little, 5>>, 
    "abcde", "dstmac", <<1, 2, 3, 4, 1234:32/little, 1, 4:16/little>>, "love"],'''
    '''icc6si4s4sic5s6s4sich4s'''
    receiveData = "";
    fieldname = ['time', 'protocoltype', 'msgtype',
                 'srcmac', 'nodeid', 'nodeip', 'srcip', 'srcport', 'srcid_len', 'srcid',
                 'dstmac', 'dstip', 'dstport', 'language_flag', 'msg_len1', 'msg_len2', 'msftext']
    def connectionMade(self):
        clnt = self.clnt = self.transport.getPeer().host
        print '...connected from:', clnt
    def dataReceived(self, data):
        #self.transport.write('[%s] %s'% (ctime(),data))
        #self.transport.write('[%s] %s' % (ctime(), 'x'))
        self.receiveData = self.receiveData + data
        #receiveData = receiveData + data
        #print self.receiveData
        length = 0
        head = 0
        head_len = 4
        body = 0
        
        while len(self.receiveData) >= head_len:
            head = self.receiveData[0:head_len]
            length = struct.unpack('i', head)[0]
            print 'length', length
    
            if len(self.receiveData) >= length & length != 0:
                print 'head', head
                
                self.onepckgdt = self.receiveData[0:length]
                self.receiveData = self.receiveData[length:]
                
                ###
                i1 = struct.unpack("c", self.onepckgdt[32])[0]
                print 'i1', ord(i1)
                tmp1 = self.onepckgdt[32 + 1 + ord(i1) + 15:32 + 1 + ord(i1) + 15 + 2]
                print 'length of tmp1', len(tmp1)
                tmp2 = struct.unpack("BB", tmp1)
                i2 = tmp2[0] + tmp2[1] * 256
                print 'i2', i2
                ###
                self.onepckgdt = self.onepckgdt[head_len:length]
                print "!iBB6si4s4siB" + str(ord(i1)) + "s" + "6s4siB" + "BB" + str(i2) + "s"
                body1 = struct.unpack("iBB6si4s4siB" + str(ord(i1)) + "s" + "6s4siB" + "BB" + str(i2) + "s", self.onepckgdt)
                
                insrt2MySQL(self.fieldname,body1)

                print self.receiveData
                print len(self.receiveData)
                ###
            else:
                break
        #print receiveData
        #for data in receiveData:
        #    print ord(data)
        print '==='

def insrt2MySQL(fieldname, fieldvalue):
    print "-" * 66
    print 'len of fieldname', len(fieldname)
    print 'len of fieldvalue', len(fieldvalue)
    dict = {}
    for i in range(len(fieldvalue)):
        print fieldname[i], ":", type(fieldvalue[i]), fieldvalue[i]
        dict[fieldname[i]]=fieldvalue[i]
        print fieldname[i], ":", type(dict[fieldname[i]]), dict[fieldname[i]]
    print
    
    print "insert into msn(time, protocoltype)"
    print " values(",dict['time'],",",dict['protocoltype'],")"
    print "insert into msn(time, protocoltype)"+" values("+str(dict['time'])+","+str(dict['protocoltype'])+")"
    ###
    
    db=MySQLdb.connect(host="192.168.0.231",user="root",passwd="admin",db="test",charset="utf8")
    cursor=db.cursor()
    #sql statement
    #cursor.execute("insert into person(name, age, gender) values('wangzhi','25','male')")
    sql = "insert into msn(time, protocoltype) values(%s, %s)"
    cursor.execute(sql,(dict['time'], dict['protocoltype']))
    cursor.execute("select * from msn")
    #get the result set
    result=cursor.fetchall()
    #iterate thtough the result set
    for i in result:
        print(i) 
    print 
    
    cursor.execute("select LAST_INSERT_ID()")
    result = cursor.fetchall()
    for i in result:
        print(i) 
    print
     
    cursor.close
    pass

factory = protocol.Factory()
factory.protocol = TSServProtocol
print 'waiting for connection...'
reactor.listenTCP(PORT, factory)
reactor.run()

 

 

 

%% Author: Administrator
%% Created: 2009-3-10
%% Description: TODO: Add description to kvs
-module(kvs6).

%%
%% Include files
%%

%%
%% Exported Functions
%%
-export([start/0, st/2]).
-export([start1/0]).
-export([start_/0]).
-export([m/2, q/2, y/2]).
  
%%
%% API Functions
%%

%% Return the Socket Handler.
start() -> 
	{ok, Socket} = gen_tcp:connect("192.168.0.93", 9090, [binary, {packet, 0}]),
	Socket.

start1() -> 
	{ok, Socket} = gen_tcp:connect("localhost", 9090, [binary, {packet, 0}]),
	Socket.

start_() -> 
	{ok, Socket} = gen_tcp:connect("localhost", 9090, [binary, {packet, 0}]),
	Data1 = [<<2:32, 1, 10>>, "srcmac", <<1234:32/little, 1, 2, 3, 4, 1, 2, 3, 4, 1234:32/little, 5>>, "abcde", "dstmac", <<1, 2, 3, 4, 1234:32/little, 1, 4:16/little>>, "hate"],
	sdpckg(Socket, Data1, 1).

st(Socket, Data) ->
	_data = list_to_binary(Data),
	gen_tcp:send(Socket, _data).

m(Socket, Repeate) ->
	Data1 = [<<Repeate:32/little, 1, 10>>, "srcmac", <<1234:32/little, 1, 2, 3, 4, 1, 2, 3, 4, 1234:32/little, 5>>, "abcde", "dstmac", <<1, 2, 3, 4, 1234:32/little, 1, 4:16/little>>, "love"],
	sdpckg(Socket, Data1, Repeate).

q(Socket, Repeate) ->
	Data1 = [<<1:32/little, 2, 34, 1234:32/little, 1, 2, 3, 4>>,  "srcmac", <<1, 2, 3, 4, 12345678:32/little>>],
	sdpckg(Socket, Data1, Repeate).

y(Socket, Repeate) ->
	Data1 = [<<1:32/little, 3, 1234:32/little, 1, 2, 3, 4>>,  "srcmac", <<1, 2, 3, 4, 1234:32/little>>, "dstmac", <<1, 2, 3, 4, 1234:32/little, 1, 5>>, "abcde", <<5>>, "fghij",<<4:16/little>>, "love"],
	sdpckg(Socket, Data1, Repeate).

sdpckg(Socket, Data1, Repeate) ->
	_data = list_to_binary(Data1),
	Head = [<<(size(_data)+4):32/little>>],
	_head = list_to_binary(Head),
	L = lib_misc:for(1, Repeate, fun(I)->_data end),
	mylists:map(fun(X)->gen_tcp:send(Socket, _head), gen_tcp:send(Socket, X) end, L).

 

 

 

 

         很明显Python本身的基础unpack在解决一些复杂问题时候力有不逮。struct模块允许创建一个等效于C结构的字符串,可以读写那些非Python程序生成的二进制文件。或者用于不同程序的网络通信。

         在其他语言中,我们完全可以为变长类型和复杂类型定义新的标示,如“2X”,或者“nList”等等。

 

         总而言之,JSON系列和byte[]系列的处理,进过一些考虑和工具类的构建,应该为各自找到较合适的应用场景。

 

1
0
分享到:
评论

相关推荐

    基于JSON实现传输byte数组过程解析

    JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,广泛用于服务器与客户端之间的数据传递,因为它的结构清晰、易于阅读和编写,同时也方便机器解析和生成。然而,JSON本身并不直接支持二进制数据的...

    Delphi10 JSon 基本读写例子,Delphi11 JSON 读写Demo

    本文将深入探讨Delphi 10和Delphi 11中对JSON进行基本读写操作的方法。 在Delphi 10和Delphi 11中,开发者可以使用内置的`System.JSON`单元来处理JSON数据。这个单元提供了一系列类,如`TJSONObject`, `TJSONArray`...

    WinformC#解析Json和使用范例

    Byte[] data = client.DownloadData(sUrl); string str = Encoding.UTF8.GetString(data); MyClass obj= JsonConvert.DeserializeObject(str); this.message = obj.message; this.nu = obj.nu; this.ischeck =...

    安卓 JSON实现对象和数组的相互转换

    以下是一个简单的`GsonUtil`类实现,包含两个主要方法:`jsonToObject`和`objectToJson`。 ```java import com.google.gson.Gson; public class GsonUtil { private static Gson gson = new Gson(); // 将JSON...

    利用Google Gson实现JSON字符串和对象之间相互转换

    在Java开发中,数据交换和存储常常涉及到JSON格式。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。Google Gson库提供了一个强大的工具,使得Java...

    C#中二进制数组转换,二进制序列化和json序列化方法

    本篇将深入探讨如何在C#中进行二进制数组与常规数组之间的转换,以及二进制序列化和JSON序列化的应用及其反序列化过程。 首先,让我们来看看二进制数组与常规数组之间的转换。在C#中,二进制数组通常用byte[]表示,...

    c#实现object与byte[]互转

    在C#中,实现object与byte[]互转是一种常见的需求,特别是在网络通信和数据存储中。这篇文章将详细介绍如何将object转换为byte[],并介绍相关的知识点。 序列化 序列化是将对象转换为二进制数组的过程。C#提供了...

    C++版轻量级JSON库 JsonLite是一个Json的C++实现,可以生成和解析JSON

    C++版轻量级JSON库 JsonLite是一个Json的C++实现,可以生成和解析JSON,除了依赖C/C++标准库 以外不依赖任何第三方库,可以移植到任何平台上。

    Android byte[] 和 String互相转换

    在Android开发中,数据在内存和磁盘之间传输时,我们经常需要在`byte[]`(字节数组)和`String`之间进行转换。这是因为`byte[]`适合处理二进制数据,如图片、音频文件等,而`String`则更适合存储文本信息。本篇将...

    net Json 序列化和反序列化

    只要对json和序列化和反序列化总结,以及代码的案例:我们很多时候会涉及到几个序列化对象的使用:DataContractJsonSerializer,JavaScriptSerializer 和 Json.NET。

    C#的基本类型和属性方法:如何解析和处理JSON的数据.rar

    JSON(JavaScript Object Notation)是数据交换格式的一种,因其简洁和易于阅读的特性,被广泛应用在网络通信和数据存储中。本教程将深入探讨如何在C#中解析和处理JSON数据,这对于进行socket通信、构建机器人程序或...

    Android读取本地json文件的方法(解决显示乱码问题)

    在Android应用开发中,有时我们需要从本地存储的JSON文件中读取数据,这通常涉及到文件I/O操作和字符编码处理。以下将详细讲解如何在Android中读取本地JSON文件,并解决可能出现的显示乱码问题。 1. **读取本地JSON...

    Delphi XE + IdHTTPServer + utf8转换 + json解析(源码+测试可用)

    在Delphi XE中,可以使用TJSONObject和TJSONParser等类来解析和生成JSON数据。这个项目表明,服务器会接收到JSON格式的请求数据,然后进行解析,处理后再以JSON格式回应。 源码和测试可用性意味着开发者可以深入...

    c#JSON文件读取写入MD5生成

    **JSON(JavaScript Object Notation)** 是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。在C#中,我们可以使用`System.Text.Json`或第三方库如Newtonsoft.Json(Json.NET)来处理JSON...

    C#编写上位机使用UDP给单片机发送Json格式数据

    byte[] sendBytes = Encoding.UTF8.GetBytes(jsonString); udpClient.Send(sendBytes, sendBytes.Length); ``` 5. **关闭UdpClient**: 发送完数据后,别忘了释放资源: ```csharp udpClient.Close(); ``` ...

    C# Json格式的转换

    在IT行业中,JSON(JavaScript Object Notation)是一种广泛使用的轻量级数据交换格式,它易于人阅读和编写,同时也易于机器解析和生成。在C#编程语言中,处理JSON格式的数据转换是常见的任务,尤其在Web服务、API...

    json小demo

    在本文中,我们将深入探讨如何在Golang中处理JSON数据,特别关注如何接收和解析JSON字符串。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,被广泛应用于Web服务和API开发中。Golang作为一门强类型...

    bson_json.zip

    err := json.Unmarshal([]byte(jsonStr), &bsonData) if err != nil { panic(err) } fmt.Println(bsonData) // 输出:map[name:Bob age:25] } ``` 在这个示例中,我们将JSON字符串解析到一个空的`bson.M`变量...

    android HTTP通信例子(json数据传递)

    首先,我们要了解JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。在Android中,我们通常使用`org.json`库或者Gson库来处理JSON数据。 1. **设置网络...

Global site tag (gtag.js) - Google Analytics