java - 将多张照片从服务器发送到客户端卡在一个while循环中
问题描述
我正在构建一个服务器/客户端应用程序,其中包括发送和保存有关照片的信息。
我设法一次成功地将 1 张照片从客户端发送到服务器。现在,我正试图让服务器向客户端发送多张照片。
我使用了与之前相同的代码并将其放入 for 循环中。但是,当我运行代码时,客户端会卡在while
循环中。特别奇怪的是,如果我要求服务器发送 3 张照片,客户端会成功接收 3 张照片并正确完成前 2 个循环,包括 while 和 for(我在控制台上通过一些打印观察到这一点)。但是,它不会while
在最后一次迭代中离开循环。我还注意到,如果我关闭服务器,客户端能够完成循环。
我想知道为什么客户端会卡在 while 循环的最后一次迭代中,即使它似乎正确接收了所有图像(我可以打开它们)。
我在服务器端使用的代码如下:
for (int i=0; i<n;i++) {
try {
//photo
File f = new File("photo.jpg");
BufferedInputStream reader = new BufferedInputStream( new FileInputStream( f ) );
//sending the photo
byte[] buffer = new byte[ 4096 ];
int bytesRead;
while ( (bytesRead = reader.read(buffer)) != -1 ) {
//ObjectOutputStream outStream is being passed to the function as an argument
outStream.write( buffer, 0, bytesRead );
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
它有点简化,因为实际上我正在遍历照片列表并f
在每个周期进行更新。
客户端的代码如下所示:
for (int j=0; j<n; j++) {
try {
File result = new File("fromServer.jpg");
BufferedOutputStream out2 = new BufferedOutputStream( new FileOutputStream( result ) );
byte[] buffer = new byte[ 4096 ];
int bytesRead;
//ObjectInputStream in was created earlier in the code, inside the same function
while ( (bytesRead = in.read( buffer )) != -1 ) {
out2.write( buffer, 0, bytesRead );
}
out2.flush();
out2.close();
} catch (IOException e3) {
e3.printStackTrace();
}
}
再一次,我简化了代码,因为文件名和位置也在每次迭代中更新,但这是这个想法的核心。
我想知道为什么客户端不会在最后一张图片上留下 while 循环。先感谢您。
解决方案
所示方法不适用于多个文件。您需要指出一个文件的结束位置和下一个文件的开始位置。例如,首先发送文件的数量(这样接收方就知道它需要循环多少次),然后对于每个文件,在发送文件字节之前发送文件的大小(这样接收方就知道何时停止读取文件和准备下一个文件)。
尝试更多类似的东西:
try {
outStream.writeInt(n);
for (int i = 0; i < n; i++) {
File f = new File("photo.jpg");
long fileSize = f.length();
outStream.writeLong(fileSize);
BufferedInputStream reader = new BufferedInputStream( new FileInputStream( f ) );
byte[] buffer = new byte[ 4096 ];
int bytesRead;
long curr = 0;
while (curr < fileSize) {
bytesRead = reader.read(buffer, 0, (int) Math.min(fileSize - curr, (long) 4096));
if (bytesRead == -1) {
// premature EOF, receiver is expecting more bytes
// than are actually available (should not happen, unless
// someone else is manipulating the file while we have it
// open), so just fail here ...
throw something;
}
outStream.write( buffer, 0, bytesRead );
curr += bytesRead;
}
reader.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
try {
int n = in.ReadInt(n);
for (int j = 0; j < n; j++) {
long fileSize = in.readLong();
File result = new File("fromServer" + Integer.toString(j) + ".jpg");
BufferedOutputStream out2 = new BufferedOutputStream( new FileOutputStream( result ) );
byte[] buffer = new byte[ 4096 ];
int bytesRead;
long curr = 0;
while (curr < fileSize) {
bytesRead = in.read(buffer, 0, (int) Math.min(fileSize - curr, (long) 4096));
if (bytesRead == -1) {
// sender disconnected prematurely, just fail here ...
throw something;
}
out2.write(buffer, 0, bytesRead);
curr += bytesRead;
}
out2.flush();
out2.close();
}
}
catch (IOException e3) {
e3.printStackTrace();
}
推荐阅读
- r - 更改满足条件的数据框列中的值
- google-cloud-platform - 最新别名不适用于 gcloud secrets 版本销毁
- git - 警告在 git commit
- python - 处理来自 QAudioProbe 的信号
- google-colaboratory - 神经网络记忆
- ios - Flutter Xcode build failed 错误无法生成进程
- python - 将部分值分配给数据集中的一组特征,涵盖python中没有小数和余数的总值
- windows - 配置:配置中缺少名称 WorldDatabaseInfo
- mongodb - mongodb pull 功能为什么不能在我的情况下工作?
- laravel - Laravel:是否可以直接从书籍集合中获取所有作者而无需循环?