日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/10 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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不太適用把應該!

總結

以上是生活随笔為你收集整理的JAVA使用ByteArrayOutputStream、ByteArrayInputStream将对象序列化反序列化,通过JAVA socket实现对象在网络中传输的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。