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()返回的值是非堵塞的,可以被多个线程访问
在对方释放连接后,也要释放本地的连接.