java socket大數(shù)據(jù)傳輸丟失問題及解決
java socket大數(shù)據(jù)傳輸丟失
最近遇見一個問題。利用java 的socket進行數(shù)據(jù)傳輸時,當數(shù)據(jù)量過大,比如4w個字節(jié)。
這時候我在客戶端輸出流將數(shù)據(jù)發(fā)送給服務器。
服務器如果利用數(shù)組接收時(即is.read(byte[])方法),接收到的數(shù)據(jù)不全。網(wǎng)上解決方法。
一、分批發(fā)送,分批讀取,并不要直接讀取
將輸入輸出流利用BufferedInputStream包裝。
實測這種方法不能根本上解決問題,治標不治本。還是會有概率丟失。
二、實際上,數(shù)據(jù)是不會丟失的
即使輸入數(shù)據(jù)過大導致溢出。數(shù)據(jù)也不會丟失。
根據(jù)觀察,應該只是數(shù)據(jù)還沒有傳輸過來,但是利用is.read(byte[])方法時,即使讀取到的數(shù)據(jù)不到byte[]數(shù)組長度時,該方法也可以進行下去,不會阻塞?。?!
譬如以下代碼:
public class Test { @org.junit.Test public void server() throws IOException { ServerSocket serverSocket = new ServerSocket(8080); while (true){ Socket accept = serverSocket.accept(); InputStream is = accept.getInputStream(); byte[] bytes = new byte[5]; int len = is.read(bytes); System.out.println(Arrays.toString(bytes));//發(fā)送端發(fā)送的數(shù)據(jù)只有兩個字節(jié),我們接收端設置為5個字節(jié)的字節(jié)數(shù)組,結果打印[1,2,0,0,0],而不會在上一步阻塞 } } @org.junit.Test public void client() throws IOException { Socket socket = new Socket("127.0.0.1",8080); OutputStream os = socket.getOutputStream(); os.write(new byte[]{1,2}); } }
從這個例子我們就知道為什么會丟失數(shù)據(jù)了。
原因有兩點:
- 網(wǎng)絡延時
- inputStream.read(byte[])方法讀取的數(shù)據(jù)長度不一定等于byte[]數(shù)組長度
根據(jù)以上兩點,修改后的接收端代碼應該如此。
public static byte[] readData(InputStream is,int length) throws IOException { byte[] bytes = new byte[length]; int index = 0; int len = 0; while(index < length){ len = is.read(bytes,index,length - index); //每次讀取完判斷數(shù)據(jù)是否全部讀取完畢 if(len > 0){ index += len; }else { break; } } return bytes; }
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
解決Java中SimpleDateFormat線程不安全的五種方案
SimpleDateFormat 就是一個典型的線程不安全事例,本文主要介紹了解決Java中SimpleDateFormat線程不安全的五種方案,需要的朋友們下面隨著小編來一起學習學習吧2021-05-05面試題:Java 實現(xiàn)查找旋轉數(shù)組的最小數(shù)字
這篇文章主要介紹了Java 實現(xiàn)查找旋轉數(shù)組的最小數(shù)字,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07Java 8 Stream 的終極技巧——Collectors 功能與操作方法詳解
這篇文章主要介紹了Java 8 Stream Collectors 功能與操作方法,結合實例形式詳細分析了Java 8 Stream Collectors 功能、操作方法及相關注意事項,需要的朋友可以參考下2020-05-05spring boot攔截器實現(xiàn)IP黑名單實例代碼
本篇文章主要介紹了spring boot攔截器實現(xiàn)IP黑名單實例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04IntelliJ?IDEA?2023.2最新版激活方法及驗證ja-netfilter配置是否成功
隨著2023.2版本的發(fā)布,用戶們渴望了解如何激活這個最新版的IDE,本文將介紹三種可行的激活方案,包括許可證服務器、許可證代碼和idea?vmoptions配置,幫助讀者成功激活并充分利用IDEA的功能,感興趣的朋友參考下吧2023-08-08springboot bean循環(huán)依賴實現(xiàn)以及源碼分析
最近在使用Springboot做項目的時候,遇到了一個循環(huán)依賴的 問題,所以下面這篇文章主要給大家介紹了關于springboot bean循環(huán)依賴實現(xiàn)以及源碼分析的相關資料,需要的朋友可以參考下2021-06-06