Java Socket循環(huán)接收數(shù)據(jù)readLine()阻塞的解決方案
寫在前面
只能說基礎不牢吧,代碼邏輯一切OK,就是接收不到服務器信息,發(fā)送沒問題。
因為服務器不是我能控制的,只能在客戶端想辦法解決,后來斷點知道了readLine()阻塞的情況,大無語呀,阻塞好是好,但你要換行符,我哪知道服務器給的是什么。
這里socket的連接之類的代碼很多,就不重復貼了,只放些解決方案供有同樣問題的朋友參考
解決方案一 加換行符
就是上面提到的readLine()要換行符才知道傳送完成,所以這個只能是服務器端發(fā)送數(shù)據(jù)給客戶端時,結尾一定要加個\r或\n
又或者使用 println() 發(fā)送數(shù)據(jù)
如果服務器客戶端都是你維護,那這個解決方案最簡單高效。
以下代碼當個參考,m_clientSocket 即是服務端通信用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() 方法
這里記得新開線程或用異步任務執(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();
}總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
@ConfigurationProperties遇到的坑及解決
這篇文章主要介紹了解決@ConfigurationProperties遇到的坑,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
使用Feign調(diào)用注解組件(實現(xiàn)字段賦值功能)
這篇文章主要介紹了使用Feign調(diào)用注解組件(實現(xiàn)字段賦值功能),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
淺析springboot通過面向接口編程對控制反轉(zhuǎn)IOC的理解
這篇文章主要介紹了springboot通過面向接口編程對控制反轉(zhuǎn)IOC的理解,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2020-08-08
mybatis-plus使用generator實現(xiàn)逆向工程
mybatis-plus-generator在3.5.0以及以后的版本使用新的方式逆向生成代碼,本文主要介紹了mybatis-plus使用generator實現(xiàn)逆向工程,具有一定的參考價值,感興趣的可以了解一下2022-05-05

