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

逻辑是这样,双方都实现建立连接,服务器监听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;
}