Java客户端上传txt文件至服务器转大写返回无响应问题排查
问题排查与修正方案
我来帮你梳理下代码里的几个关键问题,这些问题直接导致了程序没有任何效果:
1. 双向阻塞死锁
客户端写完文件数据后,没告知服务器“数据已发送完毕”,服务器的is.read(bytearray)会一直卡在那里等更多数据;同时客户端也在傻等服务器的响应,两边都堵死了,自然看不到任何效果。
解决办法是:客户端写完数据后,先调用os.flush()把缓存里的内容推出去,再调用sc.shutdownOutput()关闭客户端的输出流——这会给服务器发一个EOF信号,让服务器知道可以停止读取、开始处理返回了。
2. 服务器字节转字符串的逻辑完全错误
你用Arrays.toString(bytearray).toUpperCase()是个大坑!Arrays.toString(byte[])会把字节数组转成类似[65, 66, 67]这种格式的字符串,根本不是把字节对应的文本内容转成字符串。正确的做法是用读取到的有效字节数(也就是count变量)来构造字符串,还要指定编码(比如UTF-8)避免乱码。
3. 客户端接收时直接覆盖原文件
客户端用new FileOutputStream(file)直接写入原文件,这会在读取响应前就清空原文件内容,就算程序不阻塞,原文件也会被搞坏。建议输出到新文件,比如test_upper.txt。
4. 资源未正确关闭
客户端的各种流(fis、bis、fos、bos)和Socket都没正确关闭,容易导致资源泄漏。用try-with-resources语法可以自动帮你管理这些资源,不用手动写一堆close。
修正后的服务器代码
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.nio.charset.StandardCharsets; public class Assignment4_Server { public static void main(String[] args) throws IOException { byte[] bytearray = new byte[4096]; try (ServerSocket ss = new ServerSocket(4444)) { System.out.println("服务器等待客户端连接..."); Socket s = ss.accept(); try (InputStream is = s.getInputStream(); OutputStream os = s.getOutputStream()) { int count; StringBuilder sb = new StringBuilder(); // 读取所有客户端发送的内容 while ((count = is.read(bytearray)) > 0) { // 用有效字节数+UTF-8编码转成字符串 String chunk = new String(bytearray, 0, count, StandardCharsets.UTF_8); sb.append(chunk); } // 转成大写并返回 String upperData = sb.toString().toUpperCase(); os.write(upperData.getBytes(StandardCharsets.UTF_8)); os.flush(); // 确保数据全部发送 } System.out.println("处理完成,客户端连接已关闭"); } } }
修正后的客户端代码
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.nio.charset.StandardCharsets; public class Assignment4_client { public static void main(String[] args) throws IOException { File inputFile = new File("test.txt"); File outputFile = new File("test_upper.txt"); // 输出到新文件,避免覆盖原文件 byte[] bytearray = new byte[4096]; // 用try-with-resources自动管理所有资源,不用手动close try (Socket sc = new Socket("localhost", 4444); FileInputStream fis = new FileInputStream(inputFile); BufferedInputStream bis = new BufferedInputStream(fis); OutputStream os = sc.getOutputStream(); InputStream is = sc.getInputStream(); FileOutputStream fos = new FileOutputStream(outputFile); BufferedOutputStream bos = new BufferedOutputStream(fos)) { // 发送文件内容 int countS; while ((countS = bis.read(bytearray)) > 0) { os.write(bytearray, 0, countS); // 只写入实际读取到的有效字节 } os.flush(); sc.shutdownOutput(); // 告诉服务器:我发完了 // 接收服务器返回的大写内容 int countR; while ((countR = is.read(bytearray)) > 0) { bos.write(bytearray, 0, countR); // 只写入有效字节 } bos.flush(); // 确保内容写入文件 System.out.println("文件处理完成,结果已保存到test_upper.txt"); } } }
额外说明
- 我添加了
StandardCharsets.UTF_8明确指定编码,避免不同环境下出现乱码; - 发送和写入数据时都用了
count参数,确保只处理实际读取到的字节,不会把数组里残留的无效数据带进去; - 加了简单的日志输出,方便你查看程序运行状态。
内容的提问来源于stack exchange,提问作者Ashutosh
相关产品推荐
相关产品推荐

