JAVA使用ByteArrayOutputStream、ByteArrayInputStream将对象序列化反序列化,通过JAVA socket实现对象在网络中传输

1.序列化和反序列化:

  • 序列化是对象(类的实例)转换成字节数组或者字符串通过网络传输或者存储到本地文件。反序列化:就是将字节数组或字符串在转换成对象实例的过程。
  • (因为在网络中传输或者写本地文件,是不能使用对象的,tcp握手之后会建立一个字节流管道传输数据,所以要将对象转换序列化成字节序列)

2.ByteArrayOutputStream、ByteArrayInputStream:

  • 这两个流实际就内存流:顾名思义就是将数据写入内存,从内存中读取数据;
  • ByteArrayOutputStream:字节数组输出流在内存中创建一个字节数组缓冲区,所有发送到输出流的数 据保存在该字节数组缓冲区中。实际作用就是通过write()将对象各个字段写入一个字节数组,然后在使用toByteArray()将字节数据取出来,通过tcp传输给服务器
  • ByteArrayInputStream:字节数组输入流在内存中创建一个字节数组缓冲区,从输入流读取的数据保存在该字节数组缓冲区中。实际就是将客户端发送过来的消息转成byte数组,存入内存,在分批次读取数据。

代码如下:

  • 实例类:
    我这里实体类数据类型是这样的:类型和子类型都是1字节,长度是4字节就是一个int,实际数据包含两部分UUID+数据

在这里插入图片描述
(代码免费下载链接在最后)

public class Message implements Serializable {public int type;                //类型    1字节public int subtype;             //子类型   1字节public int dataLength;          //数据内容长度    4字节public String uniqueIdentifies;    //唯一标识  16字节public String details = "";             //具体内容  N字节public int getType() {return type;}public void setType(int type) {this.type = type;}public int getSubtype() {return subtype;}public void setSubtype(int subtype) {this.subtype = subtype;}public int getDataLength() {return dataLength;}public void setDataLength(int dataLength) {this.dataLength = dataLength;}public String getUniqueIdentifies() {return uniqueIdentifies;}public void setUniqueIdentifies(String uniqueIdentifies) {this.uniqueIdentifies = uniqueIdentifies;}public String getDetails() {return details;}public void setDetails(String details) {this.details = details;}@Overridepublic String toString() {return "Message{" +"type=" + type +", subtype=" + subtype +", dataLength=" + dataLength +", uniqueIdentifies='" + uniqueIdentifies + '\'' +", details='" + details + '\'' +'}';}
}
  • 客户端:
public class TcpClient {private String host = "localhost";private int port = 8189;public TcpClient() {}public TcpClient(String host, int port) {this.host = host;this.port = port;}public void chat(){try {Socket socket = new Socket(host,port);ByteArrayOutputStream bArray = new ByteArrayOutputStream();try {DataOutputStream out = new DataOutputStream(socket.getOutputStream());//序列化对象合并写入内存Message message = setMessage();System.out.println(message.details);bArray.write(message.getType());bArray.write(message.getSubtype());byte[] bytes1 = intToByte(message.getDataLength());bArray.write(bytes1,0,bytes1.length);bArray.write(message.uniqueIdentifies.getBytes(), 0, message.uniqueIdentifies.length());//这里分开写中文不会乱码了,如果message.details.getBytes()直接加入的write里会出现中文乱码byte[] bytes2 = message.details.getBytes();bArray.write(bytes2, 0, bytes2.length);bArray.flush();byte[] bytes = bArray.toByteArray();String result = new String(bytes);out.writeUTF(result);}finally {bArray.close();socket.close();}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {new TcpClient().chat();}public Message setMessage(){Message message = new Message();message.setType(0x01);message.setSubtype(0x01);message.setDetails("春❥(^_-)");message.setDataLength(16+message.getDetails().length());//16字节的UUID随便编的或者自己写个方法造也行(或者API注意16个字节,如果是多个字节需要自行修改服务器参数)message.setUniqueIdentifies(new String("WHDISakcmqSiamSq"));return message;}//将int转换成四字节public byte[] intToByte(int res) {byte[] targets = new byte[4];targets[0] = (byte) (res & 0xff);// 最低位targets[1] = (byte) ((res >> 8) & 0xff);// 次低位targets[2] = (byte) ((res >> 16) & 0xff);// 次高位targets[3] = (byte) (res >>> 24);// 最高位,无符号右移。return targets;}
}
  • 服务器:
package org2.server;import org2.message.Message;import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;/*** @author Chun* @create 2020-07-30 15:24**/
public class TcpServer {private int port = 8189;public TcpServer() {}public TcpServer(int port) {this.port = port;}public void service() {try {ServerSocket serverSocket = new ServerSocket(port);Socket socket = serverSocket.accept();ByteArrayInputStream bInArray = null;try {DataInputStream in = new DataInputStream(socket.getInputStream());String s = in.readUTF();byte[] bytes = s.getBytes();int realLength = bytes.length;System.out.println("realLength:" + realLength);bInArray = new ByteArrayInputStream(bytes);Message message = new Message();message.setType(bInArray.read());message.setSubtype(bInArray.read());byte[] bytesDataLength = new byte[4];bInArray.read(bytesDataLength, 0, 4);int i = byteToInt(bytesDataLength);message.setDataLength(i);byte[] byteUniqueIdentifies = new byte[16];bInArray.read(byteUniqueIdentifies, 0, 16);message.setUniqueIdentifies(new String(byteUniqueIdentifies));byte[] byteDetails = new byte[realLength - 22];bInArray.read(byteDetails, 0, realLength - 22);message.setDetails(new String(byteDetails));System.out.println(message);} finally {socket.close();serverSocket.close();}} catch (IOException e) {e.printStackTrace();}}public int byteToInt(byte[] arr) {int i0 = (int) ((arr[0] & 0xff) << 0 * 8);int i1 = (int) ((arr[1] & 0xff) << 1 * 8);int i2 = (int) ((arr[2] & 0xff) << 2 * 8);int i3 = (int) ((arr[3] & 0xff) << 3 * 8);return i0 + i1 + i2 + i3;}public static void main(String[] args) {new TcpServer().service();}
}

TcpClient.java 下载
Message.java 下载
TcpServer.java 下载

JAVA的ObjectOutputStream不太适用把应该!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/437492.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【转】刨根究底字符编码之二——关键术语解释(下)

关键术语解释(下) 如前所述&#xff0c;现代字符编码模型共分为5层&#xff0c;下面分层进行简要介绍。 一、第1层 抽象字符表ACR (Abstract Character Repertoire抽象字符清单)&#xff1a;明确字符的范围(即确定支持哪些字符) 1. 抽象字符表ACR是一个编码系统支持的所有抽…

【转】刨根究底字符编码之三——字符编码的由来

字符编码的由来 一、为什么需要对字符进行编码 1. 计算机一开始发明出来时是用来解决数字计算问题的&#xff0c;后来人们发现&#xff0c;计算机还可以做更多的事&#xff0c;例如文本处理。 但计算机其实挺“笨”的&#xff0c;它只“认识”010110111000…这样由0和1两个数…

SpringMVC配置没问题却却找不到页面,页面显示404

在Artifacts下此工程下新建一个lib文件夹&#xff0c;存放jar包&#xff0c;因为idea新建modules的时候不是直接创建的web项目&#xff1a; 选中lib点加号把jar导入进去&#xff0c;然后重启tomcat

【转】刨根究底字符编码之四——EASCII及ISO 8859字符编码方案

1. 计算机出现之后&#xff0c;首先逐渐从美国发展到了欧洲。由于欧洲很多国家所用到的字符中&#xff0c;除了基本的、美国也用的那128个ASCII字符之外&#xff0c;还有很多衍生的拉丁字母等字符。比如&#xff0c;在法语中&#xff0c;字母上方有注音符号&#xff1b;而欧洲…

tomcat乱码问题解决

tomcat安装目录下conf文件夹下的logging.properties文件&#xff0c;将java.util.logging.ConsoleHandler.encoding编码为GBK&#xff0c;如图&#xff1a;

【转】HMAC哈希消息认证码及算法原理

HMAC算法原理 HMAC算法是一种基于密钥的报文完整性的验证方法 &#xff0c;其安全性是建立在Hash加密算法基础上的。它要求通信双方共享密钥、约定算法、对报文进行Hash运算&#xff0c;形成固定长度的认证码。通信双方通过认证码的校验来确定报文的合法性。 HMAC算法可以用来…

RestFul风格学习

传统的url是这样的 RestFul是这样的

Angular使用Console.log()打印出来的数据没问题,点击详情后数据变了

我在一个界面添加数据使用updataEvent将对象返回给另一个界面后&#xff0c;在onUpData中处理时使用 this.xxxxx d&#xff0c;直接将地址值给了变量&#xff0c;当这个方法结束后d被重置了&#xff0c;所以this.xxx的值也消失了,这里要使用下面的方法复制一个对象出来。 this…

【转】刨根究底CSS(1):开篇

01 一道小菜 CSS很难&#xff0c;这应该是绝大多数Web开发人员的共识。 什么&#xff1f;你并不觉得很难&#xff1f;那我就先上一道小菜&#xff0c;请君品尝。 这是个乍一看&#xff0c;让人觉得很诡异的案例…… 算了&#xff0c;本来想滔滔不绝介绍一番&#xff0c;但一…

【转】刨根究底CSS(2):CSS中的各种值——初始值,就是默认值吗?

先问个非常简单的问题&#xff0c;这个问题的答案&#xff0c;相信大部分Web开发人员都自认为显而易见&#xff0c;但却又多半会答错&#xff1a;CSS属性中的初始值(initial value)&#xff0c;就是默认值(default value)吗&#xff1f; 难道不对吗&#xff1f;请往下看。 默…

台式机电脑配置单_2020年电脑配置单重点硬件参考

&#xff0c;电脑的基本配件扫盲我前面写过很多&#xff0c;相信很多小伙伴都看过了&#xff0c;没有看过的可以上我专栏参观&#xff1a;电脑神棍局-组装机专栏​www.zhihu.com配置单在本文后面两篇&#xff0c;但是建议前面花两分钟看下。游戏篇后续还有工作和视频工作站篇主…

【转】刨根究底字符编码之五——简体汉字编码方案(GB2312、GBK等)以及全角、半角、CJK

一、概述 1. 英文字母再加一些其他标点字符之类的也不会超过256个&#xff0c;用一个字节来表示一个字符就足够了(2^8 256)。但其他一些文字不止这么多字符&#xff0c;比如中文中的汉字就多达10多万个&#xff0c;一个字节只能表示256个字符&#xff0c;肯定是不够的&#…

开机cpu风扇声音大_联想拯救者R720笔记本,开机显示暗屏,二修机多故障完美修复...

【机器型号】拯救者R720-15(7代I5)【主板版号】NM-B191【故障现象】笔记本不开机接同行送修笔记本拯救者R720-15&#xff0c;7代I5的机器&#xff0c;同行描述说不开机。【维修过程】 拿到机器按下开关没反映&#xff0c;三下五除二&#xff0c;扒下这台电脑的衣服&#xff0c;…

【转】刨根究底字符编码之六——简体汉字编码中区位码、国标码、机内码、外码、字形码的区别及关系

GB2312、GBK、GB18030等GB系列汉字编码方案的具体实现方式是怎样的&#xff1f;区位码是什么&#xff1f;国标码是什么&#xff1f;内码、外码、字形码又是什么意思&#xff1f;它们是如何转换的&#xff0c;又为什么要这样转换&#xff1f; 下面以GB2312为例来加以说明。 一、…

公共链接url出错_SEO优化技巧:关于URL的优化方法

点击标题下「蓝色微信名」可快速关注URL优化需要遵循一些原则&#xff0c; 采用以下方法&#xff0c;网页的用户体验更佳&#xff0c;同时对搜索引擎更友好。01URL越短越好对于搜索引擎来说&#xff0c;只要URL不超过265Byte&#xff0c;收录就没有问题。如果使用几百个字母的U…

【转】刨根究底字符编码之七——ANSI编码与代码页

一、ANSI编码 1. 如前所述&#xff0c;在全世界所有国家和地区的文字符号统一编码的UCS/Unicode编码方案问世之前(UCS、Unicode后文有详细介绍)&#xff0c;各个国家、地区为了用计算机记录并显示自己的字符&#xff0c;都在ASCII编码方案的基础上&#xff0c;设计了各自的编…

Angular 下拉搜索框实现

今天有个需求要写一个下拉搜索框&#xff0c;本来是下拉框的&#xff0c;由于内容太多&#xff0c;所以添加一个查找功能。根据博客进行改写的。参考了他的基本框架进行实现。 效果图&#xff1a; 输入框右边的白色箭头图片下载地址 <td>xxxxxxx</td> <td sty…

新手前端练手网站_编程到底难不难学?新手入门选择哪种语言好?

以下内容适合的读者&#xff1a;想要学习编程的小白一.编程到底难不难学&#xff1f;对于这个问题我的回答是不知道&#xff0c;学会了编程的人会说好学&#xff0c;中途就放弃的人会说很难&#xff0c;任何知识想要掌握好都不是一件容易的事情。所以我决定用自己的实际行动来证…

【转】刨根究底字符编码之八——Unicode编码方案概述

Unicode编码方案概述 1. 前面讲过&#xff0c;随着计算机发展到世界各地&#xff0c;于是各个国家和地区各自为政&#xff0c;搞出了很多既兼容ASCII但互相之间又不兼容的各种编码方案(微软统一称之为ANSI编码&#xff0c;具体体现为各种ANSI代码页)。 这样一来&#xff0c;同…

Angular 自定义属性指令-禁止input框输入空格-以及删除复制内容中的空格

创建一个ts文件&#xff0c;并在module.ts中定义 import { Directive, ElementRef, HostListener, Input } from angular/core; import { FormGroup, FormControl, NgControl } from angular/forms; Directive({selector: [input-noSpace]}) export class NoSpace {constructo…