上一篇,我们遗留了一个问题,那就是Python的pickle模块,序列化后的字节流bytes,如果通过socket传给Java,Java可以反序列化吗?

我们看下demo案列(案列很简单,就是简单的信息传输,不涉及多线程和回写),验证一下就知道了:

Java服务端demo

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Test2 {public static void main(String[] args){ServerSocket serverSocket;try {serverSocket = new ServerSocket(9999);System.out.println("等待连接.......");Socket socket;socket = serverSocket.accept();  //一直阻塞System.out.println("客户端已连接!");InputStream ins = socket.getInputStream();InputStreamReader isr = new InputStreamReader(ins,"utf-8");BufferedReader bReader = new BufferedReader(isr);String line = "";StringBuffer buffer = new StringBuffer();while(!("==END==").equals(line=bReader.readLine())){System.out.println("客户端:"+line);buffer.append(line+"\n");}System.out.println("接收到的完整buffer:"+buffer.toString());ByteArrayOutputStream baos = new ByteArrayOutputStream();  ObjectOutputStream oos = new ObjectOutputStream(baos);    String str = new String(buffer);oos.writeObject(str);  byte [] strData = baos.toByteArray();ByteArrayInputStream baoi = new ByteArrayInputStream(strData);ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(baoi));try {Object Obj = ois.readObject();System.out.println(Obj.getClass());System.out.println("对象反序列化成功!");} catch (ClassNotFoundException e) {e.printStackTrace();}finally {serverSocket.close();socket.close();ins.close();isr.close();baos.close();baoi.close();oos.close();}} catch (IOException e) {e.printStackTrace();}}
}

启动服务端,如下:

Python客户端demo

#!/usr/bin/env Python3
# -*- encoding:utf-8 -*-import socket,pickleclass Employee:def __init__(self,name,sex,age,salary):self.name  = name    #姓名self.sex   = sex     #性别 self.__age = age     #年龄 私有变量 self.salary= salary  #薪资 按月算@propertydef age(self):            #age的getter属性,还记得装饰器@property的用法吗?return self.__age@age.setterdef age(self,value):      #age的setter属性self.__age = valuedef add(self,a,b):return a+bperson = Employee('张三','男',35,6000.00)s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('127.0.0.1',9999))
s.send(pickle.dumps(person)+bytes('\n==END==\n',encoding='utf-8'))

运行客户端,由于客户端没有接收部分,所以,我们直接看Java服务端

为了使Java服务端正常的运作,耍了一下小聪明,我们用Python传过来的字节流初始化了一个String对象str,因为谁也没告诉我,Python传过来的字节流里面装的究竟是啥(一堆乱码,我Java一脸懵逼),我就假设一下是字符串对象,显然,字符串对象序列化后,在反序列化后仍然是字符串,也就是Python传过来的内容,我Java这边只能胡乱猜测,猜测的结果就是又绕回去了。这就牵扯到了不同语言之间的序列化共性问题了,也就是你Python序列化后的字节流,你自己清楚该怎么反序列回去,而我Java则是按照自己的序列化规则走,因此,就导致,双方无法通过序列化后的字节流进行交流。

我们看下,Python是不是可以识别这些"乱码"

在Python中用pickle.load反序列1.txt里面的内容,还原对象如下

这就让人不淡定了,那我怎么让Python的对象序列化后的内容分享给Java,让Java也能看到呢?

记住,不管你是哪种编程语言,你肯定能识别字符串对吧,基本数据类型啊,连这都识别不了,你想干嘛,是不是想上上天啊?

好了,既然是字符串,结合上一篇所讲,在Python中,我们引入json模块,使用dumps函数将对象序列化成json串,然后,我们拿这个json串再交给Java,Java不就能识别了嘛,而且,Java还能对json串进行详细的解析,不信吗?不信,我们就来看一下demo案列:

服务端依然由Java来接收(Java需要引入相关的Jar包,这里是讲Python,Java不是重点):

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;public class ServerTest {public static void main(String[] args) {try {ServerSocket serverSocket = new ServerSocket(9999);System.out.println("等待连接.......");Socket socket = serverSocket.accept();//一直阻塞System.out.println("客户端已连接!");//如果连上了 执行下面的语句//读取输入流 看看客户端说了什么InputStream is = socket.getInputStream();InputStreamReader isr = new InputStreamReader(is,"GBK");BufferedReader bReader = new BufferedReader(isr);String line = "";while(!"==END==".equals(line =bReader.readLine())){System.out.println("客户端:"+line); JsonParser parser=new JsonParser();  //创建JSON解析器JsonObject object=(JsonObject) parser.parse(line);  //创建JsonObject对象JsonArray array=object.get("data").getAsJsonArray();    //得到为json的数组for(int i=0;i<array.size();i++){System.out.println("---------------");JsonObject subObject=array.get(i).getAsJsonObject();System.out.println("name="+subObject.get("name").getAsString());System.out.println("sex="+subObject.get("sex").getAsString());// System.out.println("age"+subObject.get("_Employee__age").getAsString());System.out.println("age="+subObject.get("age").getAsString());System.out.println("sum="+subObject.get("sum").getAsInt());}    }socket.shutdownInput();//关闭输入流//响应连接用户信息OutputStream os = socket.getOutputStream();PrintWriter  writer = new PrintWriter(os);writer.write("服务端: "+socket.getInetAddress().toString().replaceAll("/", "")+",您好!你传过来的JSON数据,我已成功接收并解析。");writer.flush();writer.close();os.close();bReader.close();isr.close();is.close();socket.close();} catch (IOException e) {e.printStackTrace();}}}

启动服务端

客户端由我们的Python来处理数据(demo和上一篇如出一辙,就不细说了)

#!/usr/bin/env Python3
# -*- encoding:utf-8 -*-import socket,pickle,jsonclass Employee:def __init__(self,name,sex,age,salary):self.name  = name    #姓名self.sex   = sex     #性别 self.__age = age     #年龄 私有变量 self.salary= salary  #薪资 按月算@propertydef age(self):            #age的getter属性,还记得装饰器@property的用法吗?return self.__age@age.setterdef age(self,value):      #age的setter属性self.__age = valuedef add(self,a,b):return a+bp1 = Employee('张三','男',35,6000.00)
#动态绑定实例的属性变量
p1.a = 4
p1.b = 5
p2 = Employee('李婷','女',25,4000.00)
p2.a = 10
p2.b = 20
p3 = Employee('王五','男',30,5000.00)
p3.a = 11
p3.b = 25L=[]
L.append(p1)
L.append(p2)
L.append(p3)def ToJson(obj):return {'name'  :obj.name,'sex'   :obj.sex ,'age'   :obj.age ,'salary':obj.salary,'sum'   :obj.add(obj.a,obj.b)}data = json.dumps(L,default=ToJson)
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('192.168.1.54',9999))
#s.send(bytes(data,encoding='utf-8'))
data = '{ "data":'+data+'}'
s.send(bytes(data+'\n==END==\n',encoding='utf-8'))
buff = []
while True:b = s.recv(1024)if b:buff.append(b)else:break;
for msg in buff:#print(msg.decode('utf-8'))print(msg.decode('gb2312'))s.close()

运行客户端,走你(不要注重demo,主要看效果)

服务端

Java处理完Python发过来的json数据之后,会告诉Python,兄弟,谢谢你啊,数据我收到了!当然,这是我说的。

客户端

本篇是对上一篇的承诺,如果我们只知道Python有个序列化和反序列化,而不知道怎么用的话,或者,我们就是自己跟自己玩,这种情况,完全不必担心反序列化会出问题,照着函数用就行;万一,让你和其他语言一起玩,你是不是就愣住了,这时候,不要怕,只要你会用Python的json模块,你就可以跟其他语言掰掰手腕了:"你要数据是吧,没问题,扔给你一个json字符串,自己玩去吧!",

Python3学习(33)--序列和反序列化(二)相关推荐

  1. 【零基础】Python3学习课后练习题(十二)

    本文是跟着鱼C论坛小甲鱼零基础学习Python3的视频学习的,课后题也是跟随每一课所附属的题目来做的,根据自己的理解和标准答案记录的笔记. 第十四课 测试题: 0.如何定义一个跨越多行的字符串吗(请至 ...

  2. python基础第三章选择结构答案-python3 学习笔记(二)选择结构、循环结构

    python3 学习笔记 python 优雅 明确 简单 1.选择结构 (1)简单判断 if else 使用格式: if  条件: 表达式1 else: 表达式2 (2)多条件判断 elif 使用格式 ...

  3. 【Golang】Go 语言 XML 的序列与反序列化实践

    Go 语言 XML 的序列与反序列化实践 导读 本文使用 Go 原生支持的包,对 XML 字符串以及 .xml 文件进行序列化与反序列化实践.同时对 Go 语言下的 JSON 序列化反序列化与 XML ...

  4. python序列类型是二维元素向量吗_Python 二级选择题

    88.下面代码的输出结果是 ( A ) print(round(0.1 + 0.2,1) == 0.3) A: True B: 0 C: 1 D: False 解释: round 是一个四舍五入的函数 ...

  5. 深度学习调参体验(二)

    深度学习调参体验(二) 激活函数选择: 常用的激活函数有relu.leaky-relu.sigmoid.tanh等.对于输出层,多分类任务选用softmax输出,二分类任务选用sigmoid输出,回归 ...

  6. python语言程序设计——python3的33个保留字

    写在这里的初衷,一是备忘,二是希望得到高人指点,三是希望能遇到志同道合的朋友. python3的33个保留字 黑色字符是在python基础语法体系中出现的,红色的是不常用的 字符 含义 True 真 ...

  7. oracle两表链接序列跳序,Oracle学习之 序列(Sequence)

    Oracle学习之 序列(Sequence) [Oracle学习]之 序列(Sequence) oracle文档:https://docs.oracle.com/cd/B28359_01/server ...

  8. Python3学习笔记之-学习基础(第三篇)

    Python3学习笔记之-学习基础(第三篇) 文章目录 目录 Python3学习笔记之-学习基础(第三篇) 文章目录 一.循环 1.for循环 2.while循环 3.break,continue 二 ...

  9. A Byte of Python3 学习笔记

    A Byte of Python3 学习笔记 第七章 控制流 1.if语句(带输入函数) 2.while语句 3.for循环 4.break.continue.return的区别 第八章 函数 8.1 ...

最新文章

  1. 计算机一直在启动修复怎么关机,电脑开机一直要启动修复,自动修复好久开不了机,然后进去系统恢复选?...
  2. 《linux内核完全剖析:基于0.12内核》读书笔记一
  3. Java代码的基本格式及注释
  4. SAP ABAP 内表使用
  5. JS 中判断一个对象是否为数组对象?
  6. 安卓案例:绘制文本图形图像
  7. Android 中ListView带复选框多选、全选、不选处理
  8. linux自带的cpu监测工具,Linux CPU实时系统监控工具mpstat
  9. ImportError: cannot import name ‘PILLOW_VERSION‘ from ‘PIL‘ (/home/user8/anaconda3/envs/FCOS/lib/pyt
  10. 探究网络信息安全问题及防范措施
  11. 程序员毕业去大公司好还是小公司好?
  12. 数据分析实战(二) 基于美国人口adult数据集R语言分析实战
  13. 关于SQLServer关键词“union all”与“order by”的矛盾
  14. 视频教程-微信小程序开发实战之番茄时钟开发-微信开发
  15. 利用python画圆
  16. android计时器
  17. Java删除Maven下的.lastUpdated文件
  18. 工作经费的开支范围_科研经费使用范围及说明
  19. PhysX之旅(初章)--PhysXは虾米?
  20. ctfshow 月饼杯(第二届) 部分WriteUp

热门文章

  1. 元宇宙时代,服装品牌们如何成为“头号玩家”?
  2. 谷歌 I/O 深度解析:Android Jetpack 最新变化
  3. linux系统怎么装搜狗输入法_Linux之Ubuntu系统安装搜狗输入法
  4. 苹果手机怎么扩大内存_怎样扩大手机内存
  5. 如何在HTML网页里添加CSS边框,css如何设置边框?
  6. Android实现有声计算器代码,android studio实现简单的计算器(无bug)
  7. 三星android+l,全键盘+安卓4.0 三星GALAXY M Pro回归
  8. 关于深度学习人工智能模型的探讨(四)(5)
  9. Effective C++ 总结
  10. 自定义View时,用到Paint Canvas的一些温故,PropertyAnimation中的ValueAnimator(动画四,“大大姐”的旋转跳跃no.2)