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 ...
随机推荐
- delete web server(nginx+apache)
#!/bin/bash conf_dir1="/usr/local/nginx/conf/vhost.d" conf_dir2="/usr/local/apache2/c ...
- 虚拟机Ubuntu16.04无法进入图形界面 The system is running in low-graphics mode
安装的虚拟机Ubuntu16.04 64位本可以正常使用,在安装了许多软件包(caffe)后不知哪里配置出现问题,出现The system is running in low-graphics mod ...
- Java Web项目漏洞:检测到目标URL存在http host头攻击漏洞解决办法
检测到目标URL存在http host头攻击漏洞 详细描述 为了方便的获得网站域名,开发人员一般依赖于HTTP Host header.例如,在php里用_SERVER["HTTP_HOST ...
- scrapy 通过FormRequest模拟登录再继续
1.参考 https://doc.scrapy.org/en/latest/topics/spiders.html#scrapy.spiders.Spider.start_requests 自动提交 ...
- SparkCore | Rdd| 广播变量和累加器
Spark中三大数据结构:RDD: 广播变量: 分布式只读共享变量: 累加器:分布式只写共享变量: 线程和进程之间 1.RDD中的函数传递 自己定义一些RDD的操作,那么此时需要主要的是,初始化工作 ...
- eclipse安装Spring的具体步骤
1.下载spring 官网下载需要jar包放在lib中 本人分享百度云jar 链接:https://pan.baidu.com/s/1iEMwBbTTCxuCNOEdprlGhg 提取码:e7tg 2 ...
- SpringBoot使用Nacos服务发现
本文介绍SpringBoot应用使用Nacos服务发现. 上一篇文章介绍了SpringBoot使用Nacos做配置中心,本文介绍SpringBoot使用Nacos做服务发现. 1.Eureka闭源 相 ...
- 潭州课堂25班:Ph201805201 tornado 项目 第十课 深入应用异步和协程(课堂笔记)
tornado 相关说明 需求: 增加 /save 的 handler,实现异步保存指定 URL 图片的功能 从网页上得到一张图片地址,由这个地址将图片保存到服务器,并将相关数据保存到数据库 impo ...
- XVII Open Cup named after E.V. Pankratiev. Eastern GP, Division 1
A. Count The Ones $ans=b-c+1$. #include <stdio.h> using namespace std ; int a , b , c ; void s ...
- [LeetCode] Maximum Depth of N-ary Tree N叉树的最大深度
Given a n-ary tree, find its maximum depth. The maximum depth is the number of nodes along the longe ...