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 ...
随机推荐
- drop、truncate和delete的区别
TRUNCATE TABLE 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全部行.但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源 ...
- 【Linux】-- Linux上java运行环境的配置(JDK+TOMCAT)
1.JDK安装 安装之前首先要查询软件是否存可以直接使用yum安装 yum search java | grep open 选择需要的版本安装 注意:*星号代表下载该版本的所有文件,不能少. 验证是否 ...
- 【java】-- 多线程快速入门
1.什么是进程?什么是线程?两者区别? 1.每个正在系统上运行的程序都是一个进程,每个进程包含一到多个线程,多线程处理就是允许一个进程中在同一时刻执行多个任务. 2.线程是一组指令的集合,或者是程序的 ...
- 第七篇 Flask 中路由系统以及参数
Flask中的路由系统其实我们并不陌生了,从一开始到现在都一直在应用 @app.route("/",methods=["GET","POST" ...
- The Apache HBase™ Reference Guide
以下内容由http://hbase.apache.org/book.html#getting_started节选并改编而来. 运行环境:hadoop-1.0.4,hbase-0.94.22,jdk1. ...
- 05-BootStrap
今日任务 使用JQuery发送请求局部刷新页面 使用BootStrap制作一个响应式的页面 使用BootStrap制作网站的首页 教学目标 掌握什么是响应式及响应式的原理 掌握BootStrap的栅格 ...
- centos7中安装pg数据库
# centos中安装的命令 # yum install postgresql-server.x86_64 # 安装之前可以通过以下命令价差是否已经安装过 rpm -qa | grep postgre ...
- [LeetCode] Rabbits in Forest 森林里的兔子
In a forest, each rabbit has some color. Some subset of rabbits (possibly all of them) tell you how ...
- [LeetCode] Design HashMap 设计HashMap
Design a HashMap without using any built-in hash table libraries. To be specific, your design should ...
- mysql 查询 两个表中不同字段的 和,并通过两个表的时间来分组
( SELECT sum( a.cost_sum ) AS sum_cost, sum( a.phone_sum ) AS sum_phone, sum( a.arrive_sum ) AS sum_ ...