package Test; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public class SimpleSocketClient { public static void main(String[] args) { Socket socket = null; InputStream in = null; OutputStream os = null; String serverIP = "192.168.88.1"; int port = 3308; String data = "Hello"; try { // Creates a stream socket and connects it to the specified port number at the // specified IP address. socket = new Socket(serverIP, port); // 发送数据 os = socket.getOutputStream(); // Writes b.length bytes from the specified byte array to this output stream. // The general contract for // write(b) is that it should have exactly the same effect as the call write(b, // 0, b.length). os.write(data.getBytes()); // 接收数据 in = socket.getInputStream(); // System.out.println(in.available()); byte[] bs = new byte[1024]; // Reads some number of bytes from the input stream and stores them into the // buffer array b. // The number of bytes actually read is returned as an integer. This method // blocks until input // data is available, end of file is detected, or an exception is thrown. // If the length of b is zero, then no bytes are read and 0 is returned; // otherwise, there is // an attempt to read at least one byte. If no byte is available because the // stream is at the // end of the file, the value -1 is returned; otherwise, at least one byte is // read and stored // into b. int n = in.read(bs); // 输出反馈数据 System.out.println("服务器反馈: " + new String(bs, 0, n)); } catch (Exception e) { // 打印异常信息 e.printStackTrace(); } finally { try { in.close(); os.close(); socket.close(); } catch (Exception e2) { // TODO: handle exception } } } }
java.net.SocketException: Software caused connection abort: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)at java.net.SocketInputStream.socketRead(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at Test.SimpleSocketClient.main(SimpleSocketClient.java:36)
Software caused connection abort: recv failed 说明:
产生这个异常的原因有多种方面,单就如 Software caused 所示,是由于程序编写的问题,而不是网络的问题引起的.已知会导致这种异常的一个场景如下:
客户端和服务端建立tcp的短连接,每次客户端发送一次请求,服务端响应后关闭与客户端的连接.如果客户端在服务端关闭连接后,没有释放连接,继续试图发送请求和接收响应.这个时候就会出错 .这个时候客户端Socket的getOutputStream返回来的OutPutStream维护的是本地的连接状态,无法知道远程的服务端已经关闭了对应的InputStream和socket因此虽然调用了out.write(sendbuf, 0, sendbuf.length);方法,但是实际上服务端并没有接收到客户端的请求信息.因为没有抛出异常,因此造成了误以为客户端请求发送成功的假象.
接下来调用InputStream的in.read(header, 0, 14);方法.因为这次要读取服务端的信息,因此产生了Software caused connection abort: recv failed的异常
总结产生原因,在服务端/客户端单方面关闭连接的情况下,另一方依然以为
tcp连接仍然建立,试图读取对方的响应数据,导致出现
Software caused connection abort: recv failed的异常.
因此在receive数据之前,要先判断连接状态.通过inputstream的available()方法来判断,是否有响应结果.如果available()的返回值为0,说明没有响应数据,可能是对方已经断开连接,如果available()的返回值大于0,说明有响应数据.另外值得注意的是available()返回的值是非堵塞的,可以被多个线程访问
在对方释放连接后,也要释放本地的连接.