首页 > 解决方案 > 将多张照片从服务器发送到客户端卡在一个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 循环。先感谢您。

标签: javasocketsserverclient

解决方案


所示方法不适用于多个文件。您需要指出一个文件的结束位置和下一个文件的开始位置。例如,首先发送文件的数量(这样接收方就知道它需要循环多少次),然后对于每个文件,在发送文件字节之前发送文件的大小(这样接收方就知道何时停止读取文件和准备下一个文件)。

尝试更多类似的东西:

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();
}

推荐阅读