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 ...
随机推荐
- eclipse格式化代码快捷键失效
原因是与搜狗输入法的“简繁切换”快捷键冲突(取消搜狗输入法的简繁切换快捷键,即可解决)
- yagmail 实现发邮件
yagmail 实现发邮件 yagmail 可以更简单的来实现自动发邮件功能. github项目地址: https://github.com/kootenpv/yagmail 安装 pip insta ...
- 经测试,foreach循环比linq的效率高
- python之MySQL MySQLdb 推荐使用姿势,解决中文乱码
0.目录 2.setup(1) 安装步骤,可以顺带安装mysql administrator和mysql query browser(2) 安装完毕,修改 my.ini(3) 重启 mysql 服务: ...
- 为何学习matplotlib-【老鱼学matplotlib】
这次老鱼开始学习matplotlib了. 在上个pandas最后一篇博文中,我们已经看到了用matplotlib进行绘图的功能,这次更加系统性地学习一下关于matplotlib的功能. matlab由 ...
- js处理有序列表、js处理无序列表
有序列表.无序列表 显示id为s下所有的li..隐藏同样 $("#s li").show();
- Update修改方法判断该ID的数据是否超过24小时,超过不许修改
@PostMapping("/update") public Result projectUpdate(@RequestBody ProjectVoEntity projectvo ...
- Jboss getshell
Jboss 的安装需要 JDK 环境 JDK+JBOSS 包 初始环境配置 系统变量名 变量值 PATH %JAVA_HOME%\bin:%JAVA ...
- HihoCoder1338 A Game (区间DP)
<题目链接> 题目大意: 两个人轮流从一个序列中取数,他们都面临同样的二选一决策:是拿走最左边的数,还是拿走最右边的数?问先手最多能够得到的分数是多少. 解题分析: 一道比较经典的DP,因 ...
- 【ABP】工作单元——不进行事物独立执行功能
1.注入 private readonly IUnitOfWorkManager unitOfWorkManager; 2.构造 3.开启新事物 using (var unitOfWork = uni ...