套接字编程:输入流陷入循环 - read()始终返回0

时间:2011-06-29 07:26:43

标签: java sockets

服务器端代码

public static boolean sendFile() {
        int start = Integer.parseInt(startAndEnd[0]) - 1;
        int end = Integer.parseInt(startAndEnd[1]) - 1;
        int size = (end - start) + 1;

        try {
            bos = new BufferedOutputStream(initSocket.getOutputStream());
            bos.write(byteArr,start,size);
            bos.flush();
            bos.close();
            initSocket.close();
            System.out.println("Send file to : " + initSocket);
        } catch (IOException e) {
            System.out.println(e.getLocalizedMessage());
            disconnected();
            return false;
        }

        return true;
    }

客户端

public boolean receiveFile() {
        int current = 0;

        try {
            int bytesRead = bis.read(byteArr,0,byteArr.length);
            System.out.println("Receive file from : " + client);
            current = bytesRead;
            do {
                 bytesRead =
                 bis.read(byteArr, current, (byteArr.length-current));
                 if(bytesRead >= 0) current += bytesRead;
            } while(bytesRead != -1);
            bis.close();
            bos.write(byteArr, 0 , current);
            bos.flush();
            bos.close();
        } catch (IOException e) {
            System.out.println(e.getLocalizedMessage());
            disconnected();
            return false;
        }
        return true;

    }

客户端是多线程的,服务器端不使用多线程。我只是粘贴一些有问题的代码,如果你想查看所有代码,请告诉我。

在调试代码之后,我发现如果我将max thread设置为any,那么第一个线程总是卡在这个循环中。 bis.read(....)始终返回0.虽然,服务器有近距离流,但它不会退出循环。我不知道为什么......但另一个线程正常工作。

do {
     bytesRead =
     bis.read(byteArr, current, (byteArr.length-current));
     if(bytesRead >= 0) current += bytesRead;
} while(bytesRead != -1);

2 个答案:

答案 0 :(得分:2)

当你给它一个没有剩余空间的缓冲区时,

read()将返回0。 (这似乎就是这种情况)

我建议您使用DataInputStream.readFully()为您执行此操作。

dis.readFully(byteArr); // keeps reading until the byte[] is full.

如果您只是编写大字节[]或只编写一个数据,则使用缓冲流只会增加开销。你不需要它。

BTW:当你调用close()时,它会为你调用flush()。

答案 1 :(得分:2)

您的输入文件(您发送的文件有多大?)和“byteArr”有多大? 此外,当您检查读取了多少字节时,您已经两次调用bis.read(..):

    int bytesRead = bis.read(byteArr,0,byteArr.length);

您可能希望读取/发送大于缓冲区的文件,因此您可能希望执行以下操作:

        byte [] buffer = new byte[4096];
        int bytesRead;
        int totalLength = 0;

        while(-1 != (bytesRead = is.read(buffer))) {
            bos.write(buffer, 0, bytesRead);
            totalLength += bytesRead;
        }
        bos.close();
        is.close();

“是”将是一个普通的InputStream,彼得是对的,你不需要缓冲它。