Socket断开不报错(Java)
网上看了很多关于Socket的Demo,用起来挺好用也简单,不过都在断开连接时,都没有做好相关处理,导致每次主动断开时,会报错
如:
java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.idea_a.its.robot.http.SocketUtil.connectionData(SocketUtil.java:136)
at com.idea_a.its.robot.TryBServer$1$1.success(TryBServer.java:38)
at com.idea_a.its.robot.http.SocketUtil.connectSocket(SocketUtil.java:55)
at com.idea_a.its.robot.TryBServer$1.run(TryBServer.java:34)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
具体原因是在执行socket.close();的同时,相关的BufferedReader还在等待接收数据。
所以在断开之前需要执行相关输入输出的关闭动作。
socket.shutdownInput();
socket.shutdownOutput(); 并需要确保都关闭后(socket.isInputShutdown() socket.isOutputShutdown()),
才进行BufferedReader的关闭,
最终才是关闭socket; 代码如下:
/**
* 关闭
*/
public void close() throws IOException {
if (socket == null) return; socket.shutdownInput();
socket.shutdownOutput(); do {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (!socket.isInputShutdown() || !socket.isOutputShutdown()); br.close();
socket.close();
socket = null;
}
就以客户端为例:完整代码如下(根据需要自行增减):
package com.bug01.trysocket; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket; public class SocketClientUtil {
private static final String ADDRESS = "127.0.0.1";
private static final String PORT = "6666";
private Socket socket = null;
private BufferedReader br;
private static SocketClientUtil instance = null; // 此处使用单例模式
public static SocketClientUtil getInstance() {
if (instance == null) {
synchronized (SocketClientUtil.class) {
if (instance == null) {
instance = new SocketClientUtil();
}
}
}
return instance;
} /**
* 连接socket
*/
public void connectSocket(SocketConnCallBack back) throws IOException {
try {
socket = new Socket(ADDRESS, Integer.parseInt(PORT));
back.success();
} catch (IOException e) {
e.printStackTrace();
back.failure();
socket = null;
} catch (Exception e) {
e.printStackTrace();
back.failure();
}
} /**
* 发送数据
*
* @param message
*/
public void sendData(String message) throws IOException {
//判定是否socket已链接,如果未链接则尝试链接。
if (socket == null) {
connectSocket(new SocketConnCallBack() {
@Override
public void success() { } @Override
public void failure() { }
});
}
//如果尝试链接失败,则上报异常。
if (socket == null) {
throw new IOException("Socket Connect to Server Error.");
} //输出流
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os);
//向服务端写入数据
pw.println(message);
pw.flush();
} /**
* 接受数据
*/
public void SetListener(SocketCallBack back) throws IOException {
//输入流
InputStream is = socket.getInputStream();
br = new BufferedReader(new InputStreamReader(is));
//接收服务器的相应
String reply = null;
while (!((reply = br.readLine()) == null)) {
back.responseData(reply.trim());
}
} /**
* 关闭
*/
public void close() throws IOException {
if (socket == null) return; socket.shutdownInput();
socket.shutdownOutput(); do {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (!socket.isInputShutdown() || !socket.isOutputShutdown()); br.close();
socket.close();
socket = null;
} public interface SocketCallBack {
void responseData(String data);
} public interface SocketConnCallBack {
//socket连接成功
void success(); //socket链接失败
void failure() throws IOException;
}
}
Socket断开不报错(Java)的更多相关文章
- eclipse启动报错java.lang.IllegalStateException: LifecycleProcessor not initialized - call 'refresh' befo
报错: java.lang.IllegalStateException: LifecycleProcessor not initialized - call 'refresh' before invo ...
- 开着idea,死机了,关机重启。重启之后,重新打开idea报错java.lang.AssertionError:upexpected content storage modification
开着idea,死机了,关机重启.重启之后,重新打开idea报错java.lang.AssertionError:upexpected content storage modification. goo ...
- Eclipse启动报错Java was started but returned exit code=13
启动Eclipse的时候报错Java was started but returned exit code=13,这个错误的原因是由于eclipse版本与jdk版本不符导致的,可能你的eclipse是 ...
- idea中编译项目报错 java: javacTask: 源版本 1.8 需要目标版本 1.8
问题如上面所叙: > idea中编译项目报错 java: javacTask: 源版本 1.8 需要目标版本 1.8 解决方案: > Setting->Compiler->Ja ...
- 关于SpringMVC项目报错:java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/xxxx.xml]
关于SpringMVC项目报错:java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/xxxx ...
- maven web 项目中启动报错 Java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet
主要原因是maven项目里面的jar包吗,没有导入到项目中 maven web 项目中启动报错 Java.lang.ClassNotFoundException: org.springframewor ...
- zookeeper报错java.net.ConnectException: Connection refused: no further information
zookeeper报错java.net.ConnectException: Connection refused: no further information 这是在linux 启动 https:/ ...
- 【原创】大叔问题定位分享(2)spark任务一定几率报错java.lang.NoSuchFieldError: HIVE_MOVE_FILES_THREAD_COUNT
最近用yarn cluster方式提交spark任务时,有时会报错,报错几率是40%,报错如下: 18/03/15 21:50:36 116 ERROR ApplicationMaster91: Us ...
- 云笔记项目- 上传文件报错"java.lang.IllegalStateException: File has been moved - cannot be read again"
在做文件上传时,当写入上传的文件到文件时,会报错“java.lang.IllegalStateException: File has been moved - cannot be read again ...
随机推荐
- Linux-CentOS 重置root密码
1. 重启服务器,在读秒的时候按任意键,就会出现如下界面 2.接着按下e就会进入到如下界面. 将光标移动到kernel那一行,然后再一次按‘e’,进入kernel该行的编辑界面 3.这就是kernel ...
- vs 2012 更新update4 后出现问题
Could not load file or assembly 'file:///C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7 ...
- maya cmds pymel undoInfo chunk 撤销束
maya cmds pymel undoInfo chunk 撤销束 cmds.undoInfo(openChunk = 1) # your code cmds.undoInfo(closeChunk ...
- 【C#】时间类型修改
鉴于前后端分离发展的迅速.前端很多时间控件都会读UTC时间. 安利一个小知识 // // 摘要: // Creates a new System.DateTime object that has th ...
- STL复习之 map & vector --- disney HDU 2142
题目链接: https://vjudge.net/problem/40913/origin 大致题意: 这是一道纯模拟题,不多说了. 思路: map模拟,vector辅助 其中用了map的函数: er ...
- 编程菜鸟的日记-初学尝试编程-C++ Primer Plus 第6章编程练习3
#include <iostream> using namespace std; void showmenu(void) { cout<<"Please enter ...
- T分布
# T分布 # 1.T分布是统计分布的一种,同卡方分布(X2分布),F分布并称为三大分布 2.T分布又叫student-t分布,常用于根据小样本来估计呈正太分布且方差值未知的样本的均值(如果总体的方差 ...
- NOIP-质因数分解
题目描述 已知正整数n是两个不同的质数的乘积,试求出较大的那个质数. 输入描述: 输入只有一行,包含一个正整数n. 输出描述: 输出只有一行,包含一个正整数p,即较大的那个质数. #include&l ...
- (92)Wangdao.com_第二十五天_线程机制_H5 Web Workers 分线程任务_事件 Event
浏览器内核 支撑浏览器运行的最核心的程序 IE 浏览器内核 Trident内核,也是俗称的IE内核Chrome 浏览器内核 统称为 Chromium 内核或 ...
- [LeetCode] Number of Subarrays with Bounded Maximum 有界限最大值的子数组数量
We are given an array A of positive integers, and two positive integers L and R (L <= R). Return ...