HappyP19 2024-08-06 10:33 采纳率: 0%
浏览 13

java socket 输入输出流处理大批量数据

这个问题是,在客户端这边写的逻辑 与 服务器那边的读的逻辑 都没问题的情况下(因为拿小批量数据测试过没问题),只要处理大批量数据,它就会随机的在某个报错、终止,导致无法正常传输数据。

img

逻辑是这样,双方都实现建立连接,服务器监听socket一个接口:

  • 客户端:循环扫描每个文件,依次写入流 文件ID长度 (4字节) ,文件ID,文件内容长度 (4字节),文件内容,向服务器传输
  • 服务器:循环读取流,如果前4个字节返回值不为-1,则依次读上述内容

报错内容:服务器显示 数组越界,原因是它应该读4个字节的文件长度,然后以此长度来创建读文件的数组,但不知道什么原因,它直接读了文件内容,导致长度不合法(即不是预期中的四个字节)

我无法理解的是,代码逻辑应该没问题(拿小批量数据测试过了),但一旦数据过量(但前百分之60也会正常),就会报错。而且,我捕捉报错的位置,将它的子文件夹全部传输,还是正常的

这是客户端的部分代码:

OutputStream outputStream = null;
        try {
            outputStream = socket.getOutputStream();
            

            for (Document document : Docs) {

                // 写文件ID
                byte[] file_ID = document.GetDoc_ID().getBytes();
                byte[] fileIDLength = ByteBuffer.allocate(4).putInt(file_ID.length).array();
                outputStream.write(fileIDLength);
                outputStream.write(file_ID);
                
                //System.out.println("提示:" +"发送的ID长度为:" + ByteBuffer.wrap(fileIDLength).getInt() +"发送的文件ID为:"
                        //+ new String(file_ID, StandardCharsets.UTF_8));

                // 写文件内容
                ByteArrayOutputStream BOS = new ByteArrayOutputStream();
                Path filePath = document.GetDoc_File().toPath();
                byte[] buffer = new byte[8192];
                int bytesRead;
                try (InputStream inputStream = Files.newInputStream(filePath)) {
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        BOS.write(buffer, 0, bytesRead);
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
                
                byte[] file_content = BOS.toByteArray();
                byte[] EncryptedFile_content = Encryption.EncrtptEntry(file_content);

                byte[] contentLengthBytes = ByteBuffer.allocate(4).putInt(EncryptedFile_content.length).array();
                outputStream.write(contentLengthBytes);
                //System.out.println("提示:" +"发送的加密文件的长度为:" + EncryptedFile_content.length);
                outputStream.write(EncryptedFile_content);

//                byte[] contentLengthBytes = ByteBuffer.allocate(4).putInt(file_content.length).array();
//                outputStream.write(contentLengthBytes);
//                System.out.println("发送的文件的长度为:" + file_content.length);
//                outputStream.write(file_content);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            System.err.println("错误:" + "输出流获取失败:" + e.getMessage());
        }

这是服务器端的部分代码:

while (true) {
                try {
                    byte[] ID_length_bytes = new byte[4];
                    int readbyte;
                    if ((readbyte = inputStream.read(ID_length_bytes)) == -1) {
                        System.out.println("提示:" + "End of stream reached. No more data to read.");
                        break;
                    }
                    int ID_Length = ByteBuffer.wrap(ID_length_bytes).getInt();
                    byte[] file_ID_bytes = new byte[ID_Length];

                    if (ID_Length == 36) {
                        inputStream.read(file_ID_bytes);
                        String file_ID = new String(file_ID_bytes);
                        System.out.println("提示:" + "接收的文件ID长度:" + ID_Length + " 接收的文件ID为:" + file_ID);

                        byte[] contentLengthBytes = new byte[4];
                        inputStream.read(contentLengthBytes);
                        int contentLength = ByteBuffer.wrap(contentLengthBytes).getInt();
                        System.out.println("提示:" + "接收的文件长度为:" + contentLength);

                        byte[] encryptedContent = new byte[contentLength];
                        inputStream.read(encryptedContent);

                        files.put(file_ID, encryptedContent);
                    } else {
                        System.out.println("错误:" + "ID长度不合法,底层流数据读取错误");
                        inputStream.close();
                        return;
                    }
                } catch (IOException e) {
                    System.err.println(e.getMessage());
                    // Handle the connection reset, possibly break the loop or continue depending on
                    break;
                }

  • 写回答

2条回答 默认 最新

  • 谁人不识我千夜 海口龙华千小夜科技工作室官方账号 2024-08-06 10:44
    关注

    服务器本地时间一直正确吗

    评论

报告相同问题?

问题事件

  • 创建了问题 8月6日