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-07
Java 8 Stream 的終極技巧——Collectors 功能與操作方法詳解
這篇文章主要介紹了Java 8 Stream Collectors 功能與操作方法,結合實例形式詳細分析了Java 8 Stream Collectors 功能、操作方法及相關注意事項,需要的朋友可以參考下2020-05-05
spring boot攔截器實現(xiàn)IP黑名單實例代碼
本篇文章主要介紹了spring boot攔截器實現(xiàn)IP黑名單實例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04
IntelliJ?IDEA?2023.2最新版激活方法及驗證ja-netfilter配置是否成功
隨著2023.2版本的發(fā)布,用戶們渴望了解如何激活這個最新版的IDE,本文將介紹三種可行的激活方案,包括許可證服務器、許可證代碼和idea?vmoptions配置,幫助讀者成功激活并充分利用IDEA的功能,感興趣的朋友參考下吧2023-08-08
springboot bean循環(huán)依賴實現(xiàn)以及源碼分析
最近在使用Springboot做項目的時候,遇到了一個循環(huán)依賴的 問題,所以下面這篇文章主要給大家介紹了關于springboot bean循環(huán)依賴實現(xiàn)以及源碼分析的相關資料,需要的朋友可以參考下2021-06-06

