java nio socketChannel read всегда возвращает одни и те же данные - PullRequest
1 голос
/ 15 декабря 2011

На стороне клиента прочитайте код:

byte[] bytes = new byte[50]; //TODO should reuse buffer, for test only
ByteBuffer dst = ByteBuffer.wrap(bytes);
int ret = 0;
int readBytes = 0;
boolean fail = false;
try {
    while ((ret = socketChannel.read(dst)) > 0) {
    readBytes += ret;
    System.out.println("read " + ret + " bytes from socket " + dst);
    if (!dst.hasRemaining()) {
        break;
    }
    }
    int pos = dst.position();
    byte[] data = new byte[pos];
    dst.flip();
    dst.get(data);
    System.out.println("read data: " + StringUtil.toHexString(data));
} catch (Exception e) {
    fail = true;
    handler.onException(e);
}

Проблема заключается в том, что socketChannel.read () всегда возвращает положительный результат, я проверял буфер возврата, данные дублируются N раз, ему нравится, что позиция буфера сокета низкого уровня не движется вперед. Есть идеи?

Ответы [ 2 ]

0 голосов
/ 16 декабря 2011

Если сервер вернул только 48 байтов, ваш код должен быть заблокирован в методе read(), пытаясь получить 49-й и 50-й байты.Таким образом, либо ваш «50» неверен, либо вам придется реструктурировать код, чтобы читать и обрабатывать все, что вы получаете, когда вы его получаете, а не пытаться сначала заполнить буферы.И это не может быть кодом, в котором вы думаете, что всегда получаете одни и те же данные.Объяснение этому будет неудачным сжатием буфера после получения, если вы будете использовать тот же самый буфер для следующего чтения, что вам следует сделать, но ваш опубликованный код этого не сделает.

0 голосов
/ 15 декабря 2011

1: Это не может быть ошибкой!

[при условии, что в буфере есть читаемые данные] ...

Можно ожидать -1 в конце потока ... См. http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/channels/SocketChannel.html#read%28java.nio.ByteBuffer%29

Если вы постоянно получаете положительное значение от вызова read (), вам нужно будет определить, почему данные читаются постоянно.

Конечно, загадка здесь, в конечном счете, заключается в исходных данных (то есть в SocketChannel, из которого вы читаете данные).

2: объяснение возможных проблем

Если ваш сокет-канал исходит из файла REAL, который конечен, тогда ваш файл действительно большой, и в конечном итоге операция read () вернет 0 ... в конце концов ...

Если, с другой стороны, ваш сокет-канал прослушивает источник данных, который вы ОЖИДАЕТЕ, чтобы быть конечным (например, сериализованный объектный поток, например), я бы дважды проверил источник - возможно, ваш конечный поток просто производит все больше и больше данных ... и вы правильно их потребляете.

3: наконец, несколько советов

Хитрость для отладки ошибок этого типа заключается в том, чтобы поиграть с помощью ввода ByteBuffer в вашем методе чтения: хорошая вещь в ByteBuffers java.nio заключается в том, что, поскольку они более объектно-ориентированы, чем более старые пишущие байты [], вы можете очень тонкая отладка их операций.

...