今天发现个有意思的问题: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.rhkb.cn/news/320276.html

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

相关文章

JMeter 请求头信息配置详解

在进行 Web 测试和 API 测试时,正确配置 HTTP 请求头是关键步骤之一,尤其当使用诸如 JMeter 这样的强大工具时。在本文中,我将详细介绍如何在 JMeter 中有效地配置和管理HTTP请求头。 在 JMeter 中添加和配置 HTTP 请求头 步骤 1: 打开 HTT…

中间件研发之Springboot自定义starter

Spring Boot Starter是一种简化Spring Boot应用开发的机制,它可以通过引入一些预定义的依赖和配置,让我们快速地集成某些功能模块,而无需繁琐地编写代码和配置文件。Spring Boot官方提供了很多常用的Starter,例如spring-boot-star…

张大哥笔记:卖盗版网课,获利 100 万被抓

这几天刷视频,看到一个新闻,某大学生卖盗版网课,把别人2000多正版网课,以做活动名义售卖20元,获利100多万被抓。 下方图片来自:极目新闻 卖这种盗版网课,门槛低,成本低,…

揭秘!如何利用自动化工具提升抖音推广效果

亲爱的读者朋友们,你是否在为抖音的推广效果而苦恼?看着别人家的视频轻松获得大量曝光,你是否也心生羡慕?今天,我们就来分享一个秘密武器,让你轻松提升抖音推广效果! 首先,让我们来了…

为何美国多IP服务器是全自动内容采集站的最佳选择?

为何美国多IP服务器是全自动内容采集站的最佳选择? 在建设全自动内容采集站时,选择合适的服务器至关重要。而在众多选项中,美国多IP服务器被认为是最佳选择,究竟为何呢?本文将从多个方面进行深入探讨。 为何美国多IP服务器是全自动内容采集…

项目|保障房房产管理系统,政务房产解决方案

一、系统概况 保障房管理系统是是为了落实中央关于住房保障的相关政策,实现对低收入家庭住房状况的调查管理、保障计划及落实管理、保障申请及审核管理、保障户和保障房源档案管理等。 针对政府保障房产管理的一站式解决方案,专注于为解决复杂、繁琐的…

【精品毕设推荐】搜索引擎的设计与实现

点击免费下载原文及代码 摘要 我们处在一个大数据的时代,伴随着网络信息资源的庞大,人们越来越多地注重怎样才能快速有效地从海量的网络信息中,检索出自己需要的、潜在的、有价值的信息,从而可以有效地在日常工作和生活中发挥作…

【C++】stack、queue和priority_queue的模拟实现

在本篇博客中,作者将会讲解STL中的stack、queue和priority_queue的模拟实现,同时还会带大家了解一下deque这个容器。 一.什么是适配器 STL中一共有6大组件:容器,适配器,空间配置器,仿函数,迭代器…

机器学习——3.梯度计算与梯度下降

基本概念 梯度的本意是一个向量(矢量),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模&#xff0…

validation的简单使用

首先是依赖 我这里使用的是 web 工程&#xff0c;所以多一个web依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><dependency><groupId>…

10 华三vlan技术介绍

AI 解析 -Kimi-ai Kimi.ai - 帮你看更大的世界 (moonshot.cn) 虚拟局域网&#xff08;VLAN&#xff09;技术是一种在物理网络基础上创建多个逻辑网络的技术。它允许网络管理员将一个物理网络分割成多个虚拟的局域网&#xff0c;这些局域网在逻辑上是隔离的&#xff0c;但实际…

leetCode68. 文本左右对齐

基本思路&#xff1a; leetCode68. 文本左右对齐 代码 class Solution { public:vector<string> fullJustify(vector<string>& words, int maxWidth) {vector<string> res;for(int i 0; i < words.size(); i){ // 枚举有多少个单词int j i 1; //…

年轻人刮疯了,刮刮乐断货了

年轻人刮疯了 刮刮乐缺货了。 00后彩票店老板陆诗等得有点着急。她的福彩店开在深圳&#xff0c;今年4月才开门营业&#xff0c;但从开业到今天&#xff0c;刮刮乐总共就来了一回货——开业时发的20本。 那之后&#xff0c;刮刮乐就彻底断供了。原本&#xff0c;陆诗想把刮刮…

《MySQL数据类型》

文章目录 一、理解数据本身就是一种约束1.tinyint类型和 tinyint unsigned类型2.其他的int类型 二、bit类型三、float类型1.signed版本注意2.unsigned版本 四、decimal类型float 和 decimal 总结五、char类型&#xff08;固定长度&#xff09;六、varchar类型&#xff08;可变长…

【跟马少平老师学AI】-【神经网络是怎么实现的】(四)卷积神经网络

一句话归纳&#xff1a; 1&#xff09;用1个小粒度的模式&#xff0c;逐个与图像的局部区域进行运算&#xff0c;运算结果反映模式与区域的匹配程度。 2&#xff09;卷积神经网络与全连接神经网络的区别&#xff1a; 卷积神经网络的输出只与局部输入有连接。参数较少&#xff0…

N9048B PXE EMI 测试接收机,1 Hz 至 44 GHz

​ _EMI_ N9048B EMI 测试接收机 1 Hz 至 44 GHz Keysight N9048B PXE 是一款符合标准的 EMI 测试接收机&#xff0c;配有射频预选器和 LNA 设计。其实时扫描&#xff08;RTS&#xff09;功能有助于您缩短总体测试时间&#xff0c;轻松执行无间隙的信号捕获和分析。 特点 …

宏电全栈式IoT赋能供排水智能监测,护航城市生命线

城市供水、排水系统是维系城市正常运行、满足群众生产生活需要的重要基础设施&#xff0c;是城市的“生命线”。随着城市化进程加快&#xff0c;城市规模不断扩大&#xff0c;地下管线增长迅速&#xff0c;城市“生命线安全”的监管日益面临挑战。 宏电作为物联网行业的领航者…

Docker本地部署overleaf后,挖掘用户加密逻辑

overleaf的用户信息&#xff0c;保存在mongo数据库的users集合中。 用户密码则存在hashedPassword字段中 从开源的代码services\web\app\src\Features\Authentication\AuthenticationManager.js第303行可以找到密码加密逻辑。 本地可以通过下面的代码生成overleaf用户密码信息…

408数据结构-树与森林 自学知识点整理

前置知识&#xff1a;树的基本概念与性质 树的存储结构 树既可以采用顺序存储结构&#xff0c;又可采用链式存储结构。但无论采取哪种方式&#xff0c;都要求能够唯一地反映树中各结点之间的逻辑关系。 1. 双亲表示法 这种存储结构采用一组连续空间来存储每个结点&#xff0…

JetPack之ViewModel+LiveData

目录 一、概述二、LiveData 使用2.1 创建 LiveData 对象2.2 观察 LiveData 对象2.3 更新 LiveData 对象 三、编写 LiveData Demo3.1 不使用 LiveData3.2 使用 MutableLiveData3.3 使用 MediatorLiveData3.3.1 监听 2 个数据源的变化3.3.2 编写模拟 2 个数据源更新的代码 四、Vi…