Java Socket循環(huán)接收數(shù)據(jù)readLine()阻塞的解決方案
寫在前面
只能說基礎(chǔ)不牢吧,代碼邏輯一切OK,就是接收不到服務(wù)器信息,發(fā)送沒問題。
因?yàn)榉?wù)器不是我能控制的,只能在客戶端想辦法解決,后來斷點(diǎn)知道了readLine()
阻塞的情況,大無語呀,阻塞好是好,但你要換行符,我哪知道服務(wù)器給的是什么。
這里socket的連接之類的代碼很多,就不重復(fù)貼了,只放些解決方案供有同樣問題的朋友參考
解決方案一 加換行符
就是上面提到的readLine()
要換行符才知道傳送完成,所以這個只能是服務(wù)器端發(fā)送數(shù)據(jù)給客戶端時,結(jié)尾一定要加個\r
或\n
又或者使用 println()
發(fā)送數(shù)據(jù)
如果服務(wù)器客戶端都是你維護(hù),那這個解決方案最簡單高效。
以下代碼當(dāng)個參考,m_clientSocket 即是服務(wù)端通信用Socket,非連接用的ServerSocket
public void SendMessage(String msg) { new Thread(new Runnable() { @Override public void run() { try { if (m_clientSocket.isConnected()) { if (!m_clientSocket.isOutputShutdown()) { PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(m_clientSocket.getOutputStream()), true); printWriter.println(msg); } } } catch (IOException e) { log(e.getMessage()); } } }).start(); }
解決方案二 使用Read() 方法
這里記得新開線程或用異步任務(wù)執(zhí)行接收數(shù)據(jù)的邏輯
private void WaitForData() { FutureTask<Void> futureTask = new FutureTask<>(new Callable<Void>() { @Override public Void call() throws Exception { try { String charset = "GBK"; byte[] buffer = new byte[10240]; String msg; int len; InputStream inputStream = m_clientSocket.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, charset)); while (true) { if (!m_clientSocket.isInputShutdown()) { len = inputStream.read(buffer); if (len == -1) break; msg = new String(buffer, 0, len, charset); log(msg); // 拿到了接收到的數(shù)據(jù)msg后面就是自己的處理邏輯了,是打印還是其他了 } } } catch (Exception e) { log(e.getMessage()); } return null; } }); new Thread(futureTask).start(); }
解決方案三 DataInputStream
這種方法好是好,但沒有阻塞等待,會一直循環(huán)。(突然發(fā)現(xiàn)阻塞也是好東西呀)
一并貼出來供參考吧,看需要的朋友使用
private void WaitForData() { FutureTask<Void> futureTask = new FutureTask<>(new Callable<Void>() { @Override public Void call() throws Exception { int i = 0; while (true) { if (!client.isInputShutdown()) { try { DataInputStream inputStream = new DataInputStream(client.getInputStream()); byte[] buffer = new byte[inputStream.available()]; if(buffer.length != 0){ inputStream.read(buffer); String msg = new String(buffer); clientReceiveData.OnClientReceiveData(msg); } i++; log(String.valueOf(i)); } catch (Exception ee) { log(ee.getMessage()); } } } } }); new Thread(futureTask).start(); }
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java8中Lambda表達(dá)式使用和Stream API詳解
這篇文章主要給大家介紹了關(guān)于Java8中Lambda表達(dá)式使用和Stream API的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Java8具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05使用feign調(diào)用接口時調(diào)不到get方法的問題及解決
這篇文章主要介紹了使用feign調(diào)用接口時調(diào)不到get方法的問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03mybatis-plus讀取JSON類型的方法實(shí)現(xiàn)
這篇文章主要介紹了mybatis-plus讀取JSON類型的方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09SpringMVC中redirect重定向(帶參數(shù))的3種方式
Spring MVC中做form表單功能提交時,防止用戶客戶端后退或者刷新時重復(fù)提交問題,需要在服務(wù)端進(jìn)行重定向跳轉(zhuǎn),本文主要介紹了SpringMVC中redirect重定向(帶參數(shù))的3種方式,感興趣的可以了解一下2024-07-07SpringBoot JdbcTemplate批量操作的示例代碼
本篇文章主要介紹了SpringBoot JdbcTemplate批量操作的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-04-04springboot中如何實(shí)現(xiàn)kafa指定offset消費(fèi)
這篇文章主要介紹了springboot中如何實(shí)現(xiàn)kafa指定offset消費(fèi),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-12-12SpringBoot中的@ControllerAdvice注解原理詳解
這篇文章主要介紹了SpringBoot中的@ControllerAdvice注解原理詳解,在SpringBoot應(yīng)用程序啟動過程中,Spring會掃描所有的類,尋找?guī)в蠤ControllerAdvice注解的類這些方法會被添加到一個映射表中,以便后續(xù)處理異常時能找到對應(yīng)的處理方法,需要的朋友可以參考下2024-01-01關(guān)于SpringBoot2.7.6連接nacos遇到的一些問題
這篇文章主要介紹了關(guān)于SpringBoot2.7.6連接nacos遇到的一些問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06