Программирование сокетов: Inputstream застрял в цикле - read () всегда возвращает 0 - PullRequest
0 голосов
/ 29 июня 2011

Код на стороне сервера

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 ]

2 голосов
/ 29 июня 2011

Насколько велик ваш входной файл (тот, который вы отправляете?) И насколько "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();

"is" будет простым InputStream, Питер прав, вам не нужно его буферизовать.

2 голосов
/ 29 июня 2011

read () вернет 0, когда вы дадите ему буфер без места.(Что, по-видимому, здесь имеет место)

Я бы предложил вам использовать DataInputStream.readFully (), который сделает это за вас.

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

Если вы пишете только большой байтили только запись одного фрагмента данных, использование буферизованного потока просто увеличивает издержки.Вам это не нужно.

Кстати: когда вы вызываете close (), он вызовет flush () для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...