产生原因

  1. 在创建客户端和服务端后,出现java.net.SocketException: Connection reset的错误。
    • 导致的原因

      1. 客户端或者服务端其中一端还在传输数据的途中,另外一端的socket被关闭(或者主动0关闭,或者运行异常退出导致的关闭),这时,客户端的第一个数据包传输过来后就会引发该异常。
      2. 一端在退出时,未断开连接,另外一端仍旧在连接中读取数据,就会抛出该异常,简单来说就是连接断开后其中一端仍旧在进行读写操作导致的。
    • 看错误代码:未及时关闭客户端连接,导致服务端仍旧在连接中读取数据。

      1. 客户端代码:
package com.net.TCP;import java.io.IOException;import java.io.OutputStream;import java.net.InetAddress;import java.net.Socket;//模拟客户端public class TcpClient {public static void main(String[] args) {OutputStream os=null;Socket socket =null;//1.获取服务端的IP地址+端口号try {//获取IP地址InetAddress getByName = InetAddress.getByName("127.0.0.1");//获取端口号int port=8080;//创建一个Socket连接socket = new Socket(getByName, port);System.out.println("12");//向连接发送数据,使用IO流os= socket.getOutputStream();os.write("你还号码".getBytes());Thread.sleep(3000); // 1000毫秒,即1秒钟} catch (Exception e) {e.printStackTrace();} //未对连接进行关闭}}}
2. 服务端代码:
package com.net.TCP;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.ServerSocket;import java.net.Socket;//模拟TCP协议发送消息:三次握手//模拟服务端接受数据public class TcpService {public static void main(String[] args) {try {//1.客户端需要拥有一个端口号ServerSocket serverSocket = new ServerSocket(8080);//等待客户连接Socket accept = serverSocket.accept();//读取客户信息InputStream is = accept.getInputStream();//使用管道流输出数据//创建管道流对象ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建管道流缓冲区byte[] b=newbyte[1024];int len;while ((len= is.read(b))!=-1){System.out.println("23");//通过管道流输出数据bos.write(b,0,len);}System.out.println(bos.toString());} catch (IOException e) {e.printStackTrace();}}}

只需要对两端的连接和数据流及时关闭就可以解决该问题

  • 更改后客户端:
package com.net.TCP;import java.io.IOException;import java.io.OutputStream;import java.net.InetAddress;import java.net.Socket;//模拟客户端public class TcpClient {public static void main(String[] args) {OutputStream os=null;Socket socket =null;//1.获取服务端的IP地址+端口号try {//获取IP地址InetAddress getByName = InetAddress.getByName("127.0.0.1");//获取端口号int port=8080;//创建一个Socket连接socket = new Socket(getByName, port);System.out.println("12");//向连接发送数据,使用IO流os= socket.getOutputStream();os.write("你还号码".getBytes());Thread.sleep(3000); // 1000毫秒,即1秒钟} catch (Exception e) {e.printStackTrace();}finally {try {os.close();} catch (IOException e) {e.printStackTrace();}try {socket.close();} catch (IOException e) {e.printStackTrace();}}}}
  • 更改后服务端:
package com.net.TCP;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.ServerSocket;import java.net.Socket;//模拟TCP协议发送消息:三次握手//模拟服务端接受数据public class TcpService {public static void main(String[] args) {ByteArrayOutputStream bos =null;InputStream is =null;Socket accept =null;try {//1.客户端需要拥有一个端口号ServerSocket serverSocket = new ServerSocket(8080);//等待客户连接 accept = serverSocket.accept();//读取客户信息 is = accept.getInputStream();//使用管道流输出数据//创建管道流对象bos = new ByteArrayOutputStream();//创建管道流缓冲区byte[] b=newbyte[1024];int len;while ((len= is.read(b))!=-1){System.out.println("23");//通过管道流输出数据bos.write(b,0,len);}System.out.println(bos.toString());} catch (IOException e) {e.printStackTrace();}finally {try {bos.close();} catch (IOException e) {e.printStackTrace();}try {is.close();} catch (IOException e) {e.printStackTrace();}try {accept.close();} catch (IOException e) {e.printStackTrace();}}}}