《從零開始搭建遊戲伺服器》 網路資料壓縮——Zlib演算法
前言:
關於壓縮演算法,其實有不少,例如:ZIP
、RAR
和bzip2
等,這裡我們舉例使用的Zlib
相較於前者都要簡單一些,與ZIP
、RAR等
歸檔演算法不同,它與bzip2
更為接近。那麼,下面我們就來嘗試一下Zlip在C#和Java中的實現和資料互動:C#中加密Java中解密;又或者是Java中加密C#中解密,這也體現了Zlib
的跨平臺特性。
C#方面:
通常是指客戶端,例如Unity中,可以使用此壓縮方法來壓縮網路通訊的位元組資料,伺服器接收到資料之後再進行解壓,這樣可以節約網路通訊的流量損耗。
1.下載:
其實很簡單,直接查詢第三方類庫DotNetZipLib-DevKit-v1.9
,下載其中的Ionic.Zip.dll
庫檔案,其目錄為DotNetZipLib-DevKit-v1.9\zip-v1.9\Release\Ionic.Zip.dll
,然後引入到專案中,其實也可以單獨下載.net版本的Zlib庫檔案,這裡使用到Ionic.Zip
庫是因為其中繼承了幾種壓縮演算法,為了方便後續使用,匯入到應用專案中,可以檢視其結構目錄:
Ionic.Zip
--Ionic
--Ionic.BZip2
--Ionic.Crc
--Ionic.Zip
--Ionic.Zlib
這裡我們使用到的就是Ionic.Zlib
這種壓縮演算法,這裡我們以壓縮byte[]
為例,具體的壓縮和解壓步驟:
//引入庫
using Ionic.Zlib;
2.壓縮:
//壓縮位元組陣列
byte[] newData = ZlibStream.CompressBuffer(oldData);
3.解壓:
//解壓
byte[] oldData = ZlibStream.UncompressBuffer(newData);
Java版的Zlib:
通常是指伺服器,在JDK中的java.util.zip
中就包含了內建的Zlib實現,我們只需要做簡單的封裝即可實現壓縮和解壓的功能,這裡我們封裝一下壓縮和解壓byte[]
位元組陣列的方法在工具類 ZlibUtil
中:
1.壓縮:
/**
* 壓縮
* @param data 待壓縮資料
* @return byte[] 壓縮後的資料
*/
public static byte[] compress(byte[] data) {
byte[] output = new byte[0];
Deflater compresser = new Deflater();
compresser.reset();
compresser.setInput(data);
compresser.finish();
ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);
try {
byte[] buf = new byte[1024];
while (!compresser.finished()) {
int i = compresser.deflate(buf);
bos.write(buf, 0, i);
}
output = bos.toByteArray();
} catch (Exception e) {
output = data;
e.printStackTrace();
} finally {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
compresser.end();
return output;
}
2.解壓:
/**
* 解壓
* @param data 待壓縮的資料
* @return byte[] 解壓縮後的資料
*/
public static byte[] decompress(byte[] data) {
byte[] output = new byte[0];
Inflater decompresser = new Inflater();
decompresser.reset();
decompresser.setInput(data);
ByteArrayOutputStream o = new ByteArrayOutputStream(data.length);
try {
byte[] buf = new byte[1024];
while (!decompresser.finished()) {
int i = decompresser.inflate(buf);
o.write(buf, 0, i);
}
output = o.toByteArray();
} catch (Exception e) {
output = data;
e.printStackTrace();
} finally {
try {
o.close();
} catch (IOException e) {
e.printStackTrace();
}
}
decompresser.end();
return output;
}
3.測試:
System.err.println("位元組壓縮/解壓縮測試");
String inputStr = "linshuhe.tech;linshuhe.tech;linshuhe.tech;linshuhe.tech;";
System.err.println("輸入字串:\t" + inputStr);
byte[] input = inputStr.getBytes();
System.err.println("輸入位元組長度:\t" + input.length);
byte[] data = ZlibUtil.compress(input);
System.err.println("壓縮後位元組長度:\t" + data.length);
byte[] output = ZlibUtil.decompress(data);
System.err.println("解壓縮後位元組長度:\t" + output.length);
String outputStr = new String(output);
System.err.println("輸出字串:\t" + outputStr);
執行程式碼輸出的測試結果如下:
位元組壓縮/解壓縮測試
輸入字串: linshuhe.tech;linshuhe.tech;linshuhe.tech;linshuhe.tech;
輸入位元組長度: 56
壓縮後位元組長度: 25
解壓縮後位元組長度: 56
輸出字串: linshuhe.tech;linshuhe.tech;linshuhe.tech;linshuhe.tech;
題外話:
Java中除了Zlib
這種簡單的壓縮演算法之外,還有其他幾種常用的較複雜的壓縮演算法:
名稱 | 實現方式 | 效能 |
---|---|---|
JDK GZIP | java.util.zip.GZIPInputStream/GZIPOutputStream 便可實現 |
壓縮比高,速度慢,壓縮後的資料適合長期使用 |
JDK deflate | java.util.zip.DeflaterOutputStream/InflaterInputStream 可實現 |
可指定演算法的壓縮級別,0(不壓縮)、1(快速壓縮)到9(慢速壓縮) |
LZ4壓縮演算法 | https://github.com/lz4/lz4/,https://github.com/Cyan4973/lz4.git,https://github.com/lz4/lz4.git | 對比幾種壓縮演算法裡面壓縮速度最快的 |
Snappy | Google開發的 | 速度和壓縮比都相對較優 |
速度對比結果:
Snappy
要慢於LZ4
(快速壓縮),並且壓縮後的檔案要更大。相反,LZ4
(高壓縮比)要慢於級別1到4的deflate
,而輸出檔案的大小即便和級別1的deflate
相比也要大上不少。因此如果需要進行“實時壓縮”的話我肯定會在LZ4
(快速)的JNI實現或者是級別1的deflate
中進行選擇。當然如果你的公司不允許使用第三方庫的話你也只能使用deflate
了。
更多關於Zlib的內容參考:Zlib官網
參考資料:
相關文章
- flutter之從零開始搭建(三)之 網路請求Flutter
- Python模組學習:zlib 資料壓縮Python
- 《從零開始搭建遊戲伺服器》 序列化工具(最優版Protostuff)遊戲伺服器
- 從零開始搭建屬於自己的網站網站
- 從零開始學機器學習——網路應用機器學習
- VUE從零開始環境搭建Vue
- 從零開始搭建webpack應用Web
- 從零開始搭建腳手架
- 大資料學習路線(自己制定,從零開始)大資料
- 從零開始用 Flask 搭建一個網站(一)Flask網站
- 從零開始實現放置遊戲(一):整體框架搭建遊戲框架
- 從零開始的 Jupyter 雲伺服器完全搭建指南伺服器
- 在Ubuntu機器上從零開始搭建SVN伺服器Ubuntu伺服器
- 樹莓派從零開始搭建Samba檔案伺服器樹莓派Samba伺服器
- 從零開始搭建部落格系列
- 從零開始React伺服器渲染React伺服器
- 從零開始:教你如何訓練神經網路神經網路
- 《從零開始學Python網路爬蟲》概要Python爬蟲
- Nginx網路壓縮 CSS壓縮 圖片壓縮 JSON壓縮NginxCSSJSON
- 從零開始搭建本地 Docker 開發環境Docker開發環境
- 從零開始搭建React應用(一)——基礎搭建React
- 從零開始通過 Artifactory 搭建公網的 maven 倉庫Maven
- 從零開始實現放置遊戲(三):後臺管理系統搭建遊戲
- 從零開始搭建一個 hexo 部落格。Hexo
- 從零開始搭建你的nvim ideIDE
- 從零開始搭建React全家桶環境React
- 從零開始搭建一個vue專案Vue
- VuePress從零開始搭建自己的部落格Vue
- 從零開始搭建vue.js專案Vue.js
- 從零開始搭建一個mock服務Mock
- 從零開始實現放置遊戲(一)遊戲
- 從零開始搭建webpack+react開發環境WebReact開發環境
- 從零開始做一個SLG遊戲(四):UI系統之主介面搭建遊戲UI
- 機器之心GitHub專案:從零開始用TensorFlow搭建卷積神經網路Github卷積神經網路
- 從零開始搭建一個舒適的ubuntuUbuntu
- 從零開始寫一個網頁網頁
- 從零開始一個http伺服器(六)-多路複用和壓力測試HTTP伺服器
- 從零開始機器學習機器學習