今天发现个有意思的问题:java基础篇章网络编程的报错问题,顺便看一下各个GPT的实力

问题:

一个java socket网络编程的引发的异常,具体代码Client.java、Server.java,如下

Client.java

package Test2;import java.io.*;
import java.net.Socket;public class Client {public static void main(String[] args) throws IOException {//创建对象,连接服务端Socket socket = new Socket("127.0.0.1",10000);//写入通道数据String str = "见到你很高兴!!!";OutputStream os = socket.getOutputStream();os.write(str.getBytes());//添加写入通道数据的结束标志socket.shutdownOutput();//接受返回的数据InputStream is = socket.getInputStream();InputStreamReader isr = new InputStreamReader(is);int b;while((b = isr.read()) != -1){System.out.print((char)b);}//释放资源socket.close();}
}

Server.java

package Test2;import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public static void main(String[] args) throws IOException {//创建服务端的对象ServerSocket ss = new ServerSocket(10000);//等待客户端连接Socket socket = ss.accept();//接受数据InputStream is = socket.getInputStream();InputStreamReader isr = new InputStreamReader(is);int b;while ((b = isr.read()) != -1) {System.out.print((char) b);}//返回数据String str = "高兴的不要不要的!!!";OutputStream os = socket.getOutputStream();os.write(str.getBytes());//释放资源ss.close();}
}

异常信息:

错误:Exception in thread "main" java.net.SocketException: Connection resetat java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:328)at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:355)at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:808)at java.base/java.net.Socket$SocketInputStream.read(Socket.java:966)at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:270)at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:313)at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:188)at java.base/sun.nio.cs.StreamDecoder.read0(StreamDecoder.java:137)at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:122)at java.base/java.io.InputStreamReader.read(InputStreamReader.java:169)at Test2.Client.main(Client.java:23)

我运行了代码,异常如下

如果熟悉java socket编程的人,肯定会一眼看出问题,是服务器关闭了,导致客户端继续获取数据而报的异常,而且数据流也没有关闭。

下面我把问题发给ChatGPT、讯飞星火、文心一言、通义千问、Kimi,看看他们的回答:

一:ChatGPT 3.5

这个错误通常表示服务器在尝试读取数据时,连接被重置了。这可能是因为服务器尝试读取数据时,客户端已经关闭了连接。要修复这个问题,你可以在客户端代码的写数据之后立即关闭输出流,而不是等待服务器端返回数据后再关闭连接。可以把 socket.shutdownOutput(); 放在写数据之后,这样就不会触发服务器端的连接重置了。

二:讯飞星火

这个错误是因为在客户端和服务端的代码中,没有正确地关闭输入输出流和套接字。为了修复这个问题,你需要在每个代码块的末尾添加相应的关闭语句。以下是修复后的代码:

客户端代码: 

package Test2;import java.io.*;
import java.net.Socket;public class Client {public static void main(String[] args) throws IOException {//创建对象,连接服务端Socket socket = new Socket("127.0.0.1",10000);//写入通道数据String str = "见到你很高兴!!!";OutputStream os = socket.getOutputStream();os.write(str.getBytes());//添加写入通道数据的结束标志socket.shutdownOutput();//接受返回的数据InputStream is = socket.getInputStream();InputStreamReader isr = new InputStreamReader(is);int b;while((b = isr.read()) != -1){System.out.print((char)b);}//释放资源isr.close();is.close();os.close();socket.close();}
}

服务端代码:

package Test2;import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public static void main(String[] args) throws IOException {//创建服务端的对象ServerSocket ss = new ServerSocket(10000);//等待客户端连接Socket socket = ss.accept();//接受数据InputStream is = socket.getInputStream();InputStreamReader isr = new InputStreamReader(is);int b;while ((b = isr.read()) != -1) {System.out.print((char) b);}//返回数据String str = "高兴的不要不要的!!!";OutputStream os = socket.getOutputStream();os.write(str.getBytes());//释放资源isr.close();is.close();os.close();socket.close();ss.close();}
}

三:通义千问

这个代码中,服务器端(Server)和客户端(Client)的通信逻辑存在一些问题,导致了“java.net.SocketException: Connection reset”异常。当客户端发送消息后立即关闭输出流并执行socket.shutdownOutput(),而服务器端还在读取输入流,没有及时响应和关闭连接,此时客户端可能已经关闭了连接,从而导致服务器端在读取时抛出连接重置异常。

修复方案如下:

首先,我们需要确保客户端在接收服务器回复后再关闭连接。同时,为了避免服务器端在未发送完数据时就关闭连接,我们应在服务器端发送完数据后再关闭相关资源。

修改后的客户端(Client.java)代码:

package Test2;import java.io.*;
import java.net.Socket;public class Client {public static void main(String[] args) throws IOException {// 创建对象,连接服务端Socket socket = new Socket("127.0.0.1", 10000);// 写入通道数据String str = "见到你很高兴!!!";OutputStream os = socket.getOutputStream();os.write(str.getBytes());// 添加写入通道数据的结束标志(这里不需要调用 shutdownOutput,因为后面还要接收服务器的响应)// socket.shutdownOutput();// 接受返回的数据InputStream is = socket.getInputStream();InputStreamReader isr = new InputStreamReader(is);int b;StringBuilder sb = new StringBuilder();while ((b = isr.read()) != -1) {sb.append((char) b);}System.out.println(sb.toString());// 释放资源socket.close();}
}

修改后的服务器端(Server.java)代码:

package Test2;import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public static void main(String[] args) throws IOException {// 创建服务端的对象ServerSocket ss = new ServerSocket(10000);// 等待客户端连接Socket socket = ss.accept();// 接受数据InputStream is = socket.getInputStream();InputStreamReader isr = new InputStreamReader(is);int b;StringBuilder sb = new StringBuilder();while ((b = isr.read()) != -1) {sb.append((char) b);}System.out.println(sb.toString());// 返回数据String str = "高兴的不要不要的!!!";OutputStream os = socket.getOutputStream();os.write(str.getBytes());// 确保数据已发送完毕os.flush();// 释放资源socket.close();ss.close();}
}

四:文心一言

这个错误通常发生在客户端尝试从已经关闭的socket读取数据时。在你的代码中,问题出现在服务器端在读取完客户端发送的数据之后,就关闭了ServerSocketss.close();),而不是客户端的socket(socket.close();)。关闭ServerSocket意味着服务器停止了监听新的连接,而当前已经建立的连接(socket)并不会自动关闭。

由于服务器在发送数据给客户端之前没有关闭它自己的socket输出流,客户端可以继续读取数据。但是,由于服务器关闭了ServerSocket(这是不恰当的),并且没有适当地关闭与客户端的连接(即没有调用socket.close();),客户端在读取完数据后尝试继续读取时,可能会遇到连接已经被服务器重置的情况,从而抛出SocketException: Connection reset异常。

修复这个问题的方法是,在服务器端发送完数据给客户端之后,应该关闭与客户端的连接(即调用socket.close();),而不是关闭ServerSocket。另外,服务器端在读取完客户端数据后,可能也想要发送一个明确的结束标记给客户端,以便客户端知道何时停止读取数据(尽管在这个例子中,由于你使用的是TCP,客户端可以检测到EOF(End Of File)来知道何时停止读取)。

 下面是修复后的服务器端代码:

package Test2;  import java.io.IOException;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
import java.io.OutputStream;  
import java.net.ServerSocket;  
import java.net.Socket;  public class Server {  public static void main(String[] args) throws IOException {  // 创建服务端的对象  ServerSocket ss = new ServerSocket(10000);  // 等待客户端连接  Socket socket = ss.accept();  // 接受数据  InputStream is = socket.getInputStream();  InputStreamReader isr = new InputStreamReader(is);  int b;  StringBuilder sb = new StringBuilder();  while ((b = isr.read()) != -1) {  sb.append((char) b);  }  System.out.println("Received from client: " + sb.toString());  // 返回数据  String str = "高兴的不要不要的!!!";  OutputStream os = socket.getOutputStream();  os.write(str.getBytes());  os.flush(); // 确保数据被发送出去  // 释放资源:关闭与客户端的连接  socket.close(); // 注意这里关闭的是socket,不是ss  // 当不再需要监听新的连接时,再关闭ServerSocket  // 在这个例子中,因为我们只处理一个连接,所以可以立即关闭它  ss.close();  }  
}

注意,os.flush();这一行确保了所有待发送的数据都已经被发送到网络上。在你的原始代码中,虽然这不是导致SocketException的直接原因,但它是良好的编程习惯。

此外,我添加了一个StringBuilder来累积从客户端接收到的数据,并在读取完成后打印出来,以便于调试和查看接收到的数据。在实际应用中,你可能需要根据你的需求来处理这些数据。

五:Kimi

这段代码中的错误提示是 java.net.SocketException: Connection reset,这通常意味着另一端的连接被关闭了。在这段代码中,有几个地方可能导致这个问题:

  1. Client 类中,你调用了 socket.shutdownOutput(),这将关闭输出流,但它也会向对方发送一个结束连接的信号。然而,你的 Server 类并没有正确处理这个信号,它仍然尝试读取数据,这将导致 SocketException

  2. Server 类中,你创建了 ServerSocketSocket,但是没有关闭 ServerSocket。通常,你应该在完成通信后关闭它们。

  3. Server 类中,你只在读取完输入流后发送了响应,但是没有检查是否读取完毕,这可能导致客户端在服务端发送响应之前就关闭了连接。

  4. Client 类中,你在读取完服务端的响应后关闭了 socket,但是没有检查是否读取完毕。

为了修复这个问题,你可以做以下修改:

  • 在 Client 类中,不要立即关闭 socket,而是在读取完所有响应后再关闭。
  • 在 Server 类中,发送完响应后再关闭 socket 和 ServerSocket

 下面是修复后的代码示例:

// Client 类保持不变// Server 类
package Test2;import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public static void main(String[] args) throws IOException {ServerSocket ss = new ServerSocket(10000);Socket socket = ss.accept();InputStream is = socket.getInputStream();InputStreamReader isr = new InputStreamReader(is);int b;while ((b = isr.read()) != -1) {System.out.print((char) b);}// 返回数据String str = "高兴的不要不要的!!!";OutputStream os = socket.getOutputStream();os.write(str.getBytes());os.flush(); // 确保发送所有数据// 释放资源os.close();isr.close();is.close();socket.close();ss.close();}
}

 请注意,我在 Server 类中添加了 os.flush() 来确保所有数据都被发送。同时,我按照正确的顺序关闭了流和套接字。

此外,如果你希望 Client 类在读取完所有数据后再关闭连接,你可以在读取完输入流后添加一个检查,确保已经读取完毕,然后再关闭 socket。例如:

// Client 类
// ...while((b = isr.read()) != -1){System.out.print((char)b);
}// 确保所有数据都已读取
isr.ready();// 释放资源
isr.close();
is.close();
os.close();
socket.close();
// ...

请根据你的具体需求调整上述代码。

-----------------以上就是各种GPT的回答-----------------

因此,好的编程习惯也很重要,各个GPT都表现的非常好,不过还是有一些问题。

1.ChatGPT 3.5和通义千问对于socket.shutdownOutput();的解答是错的,和这句话没有关系

2.讯飞星火和Kimi的回答是最好的,只是对异常只是抛出处理,不过对于解决普通问题够用了。

3.文心一言只把目光聚焦在解决单一问题上,没有对数据流的关闭做处理。

大家觉得哪一个更厉害呢?

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/670338.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

✌粤嵌—2024/5/6—盛最多水的容器

代码实现&#xff1a; 方法一&#xff1a;暴力解法 #define min(a, b) ((a) > (b) ? (b) : (a)) #define max(a, b) ((a) > (b) ? (a) : (b))int maxArea(int *height, int heightSize) {int ans 0;for (int i 0; i < heightSize; i) {for (int j i; j < heig…

武汉星起航:跨境电商行业领航者,一站式孵化服务引领全球趋势

在全球化日益深入的今天&#xff0c;跨境电商作为连接各国市场的桥梁&#xff0c;其重要性日益凸显。在这一潮流中&#xff0c;武汉星起航电子商务有限公司以其前瞻性的战略眼光和丰富的运营经验&#xff0c;迅速崛起为跨境电商行业的领军者。公司不仅自营亚马逊跨境电商业务&a…

一、Redis五种常用数据类型

Redis优势&#xff1a; 1、性能高—基于内存实现数据的存储 2、丰富的数据类型 5种常用&#xff0c;3种高级 3、原子—redis的所有单个操作都是原子性&#xff0c;即要么成功&#xff0c;要么失败。其多个操作也支持采用事务的方式实现原子性。 Redis特点&#xff1a; 1、支持…

核心代码分析

核心代码分析 下面的代码主要有两个作用 判断是否为扫描器或者密码爆破工具&#xff0c;进行交互握手&#xff0c;效果是扫描器直接爆3306弱口令。如果是直接连接&#xff0c;去读取设定好的文件&#xff0c;并写入本地保存。 这些函数用于从MySQL数据库中获取指定文件的内容…

3D+仿真分析:高效实现海底石油管道系统设计

Bentley AutoPIPE 助力节省寻找更佳管道路线所需的时间和成本 评估管道完整性以提高石油产量 从墨西哥湾浅水区开采石油通常需要铺设新的海底管道&#xff0c;从而在高压和高温条件下高效、安全地输送原油。 Grupo EspecializadoenObras Marinas (GEOMSA) 是墨西哥湾管道—土体…

iOS ------ JSONModel源码

一&#xff0c;JSONModel的基本使用 1&#xff0c;基本使用方法 - (instancetype)initWithDictionary:(NSDictionary *)dict error:(NSError **)err; - (instancetype)initWithData:(NSData *)data error:(NSError **)error; - (instancetype)initWithString:(NSString *)str…

239 基于matlab的EKF(扩展卡尔曼滤波)_UKF(无迹卡尔曼滤波)_PF(粒子滤波)三种算法的估计结果比较

基于matlab的EKF(扩展卡尔曼滤波)_UKF(无迹卡尔曼滤波)_PF&#xff08;粒子滤波&#xff09;三种算法的估计结果比较&#xff0c;输出估计误差&#xff0c;并单独对粒子滤波进行估计及其置信区间可视化。程序已调通&#xff0c;可直接运行。 239 EKF(扩展卡尔曼滤波) - 小红书 …

Linux中gcc/g++的使用

文章目录 前言gcc/g 前言 gcc和g即为编译器。其中gcc为c语言的编译器&#xff0c;只能编译c语言&#xff1b;g为c的编译器&#xff0c;既能编译c语言&#xff0c;又能编译c。 在前面的文章中&#xff0c;我们提到代码转换成可执行程序需要经过 预处理&#xff08;进行宏替换)…

Transformer全流程细致讲解

文章目录 1. Transformer 架构概述2. 编码器&#xff08;Encoder&#xff09;2.1 输入嵌入层&#xff08;Input Embedding Layer&#xff09;2.1.1 一个简单的示例 2.2 位置编码&#xff08;Positional Encoding&#xff09;2.2.1 Transformer中采用的位置编码方式2.2.2 公式中…

创新指南|组织健康仍然是企业创新长期绩效的关键

麦肯锡关于组织健康的最新调查结果表明&#xff0c;它仍然是当今全球市场中价值创造的最佳预测者和竞争优势的可持续来源。在本文中&#xff0c;我们将探讨最新的 OHI 结果&#xff0c;并重点介绍该指数揭示的有关领导力、数据和技术以及人才管理的一些更引人注目的见解。我们还…

uniapp文本框上下滚动问题

一个基本需求&#xff0c;textarea标签没有办法通过手拖动的方式进行滚动&#xff0c;当文字超出其容量后&#xff0c;想要编辑上面被遮挡部分的文字这边难以点到&#xff0c;电脑可以鼠标滚轮&#xff0c;但手机需要拖动但无效&#xff1a; 下面提供了我的解决思路&#xff1a…

CUDA调整指令级原语

在GPU上运行的运算密集型应用程序&#xff0c;处理器的计算吞吐量可以用它在一段时间内执行操作的数量来衡量。因为GPU有很多SIMT指令和计算核心&#xff0c;所以其峰值计算吞吐量通常比其他的处理器高。 对应用程序的吞吐量和正确性进行优化时&#xff0c;理解不同低级原语的…