Java Socket(断开不报错版)
Posted vingxu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java Socket(断开不报错版)相关的知识,希望对你有一定的参考价值。
网上看了很多关于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;
就以客户端为例:完整代码如下(根据需要自行增减):
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; } }
以上是关于Java Socket(断开不报错版)的主要内容,如果未能解决你的问题,请参考以下文章
java用httpclient 执行到httpclient.execute(request); 这句代码假死不往下执行不报错
java new object.method() 为啥不报错? [关闭]
Eclipse导入Web项目后代码不报错但项目报错(左上角有红叉)解决方案
HttpClient 中的putMethod上传100M的文件怎么设置,我上传小的不报错。20M就报java heap space 异常。