从服务器向客户端发送多张照片陷入 while 循环
Sending multiple photos from server to client stuck in a while loop
我正在构建一个 server/client 应用程序,其中包括发送和保存有关照片的信息。
我一次成功地从客户端向服务器发送了 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();
}
我正在构建一个 server/client 应用程序,其中包括发送和保存有关照片的信息。
我一次成功地从客户端向服务器发送了 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();
}