网络编程连接异常

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()返回的值是非堵塞的,可以被多个线程访问

在对方释放连接后,也要释放本地的连接.

猜你喜欢

转载自blog.csdn.net/yongwan5637/article/details/80158692