Что может привести к созданию ложного EOF в потоке сжатых данных GZip - PullRequest
0 голосов
/ 10 августа 2010

Мы транслируем данные между сервером (написанный на .Net, работающем в Windows) клиенту (написанный на Java, работающем в Ubuntu) в пакетном режиме.Данные в формате XML.Иногда клиент Java выдает неожиданный EOF при попытке распаковать поток.Содержание сообщения всегда варьируется и зависит от пользователя.Ответ от клиента также сжимается с помощью GZip.Это никогда не терпит неудачу и кажется прочным.Ответ от клиента контролируется системой.

Есть ли вероятность того, что какое-то расположение символов или некоторые специальные символы создают ложные маркеры EOF?Может ли это быть связано с пробелами?Подходит ли GZip для сжатия XML?

Я предполагаю, что код для чтения и записи из потоков ввода / вывода работает, потому что мы только иногда получаем это исключение и когда мы проверяем пользовательские данные в то время, когда кажется, чтобыть специальными символами (именно поэтому я задал вопрос), такими как знак '@'.

Есть идеи?

ОБНОВЛЕНИЕ: Фактический код в соответствии с запросом.Я думал, что это не из-за того, что я был на нескольких сайтах, чтобы получить помощь по этому вопросу, и все они более или менее имели один и тот же код.На некоторых сайтах упоминается добавленный GZip.Что-то связанное с GZip, создающим несколько сегментов?

public String receive() throws IOException {

    byte[] buffer = new byte[8192];
    ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);

    do {
        int nrBytes = in.read(buffer);
        if (nrBytes > 0) {
            baos.write(buffer, 0, nrBytes);
        }
    } while (in.available() > 0);
    return compressor.decompress(baos.toByteArray());
}
   public String decompress(byte[] data) throws IOException {
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    ByteArrayInputStream in = new ByteArrayInputStream(data);

    try {
        GZIPInputStream inflater = new GZIPInputStream(in); 
        byte[] byteBuffer = new byte[8192];
        int r;
        while((r = inflater.read(byteBuffer)) > 0 ) {
            buffer.write(byteBuffer, 0, r); 
        }
    } catch (IOException e) {
        log.error("Could not decompress stream", e);
        throw e;
    }
    return new String(buffer.toByteArray());
}

Сначала я подумал, что должно быть что-то не так с тем, как я читаю в потоке, и подумал, что, возможно, я не зациклен правильно.Затем я сгенерировал тонну данных для потоковой передачи и проверил, что они зациклены.Кроме того, тот факт, что это случается так редко и до сих пор не воспроизводимо, приводит меня к мысли, что это скорее содержание, чем сценарий.Но в этот момент я совершенно сбит с толку и, насколько я знаю, это код.

Еще раз спасибо всем.

Обновление 2:

По запросу. .Net код:

Dim DataToCompress = Encoding.UTF8.GetBytes(Data)
Dim CompressedData = Compress(DataToCompress)

Чтобы получить необработанные данные в байтах.А затем он сжимается

      Private Function Compress(ByVal Data As Byte()) As Byte()
            Try
                Using MS = New MemoryStream()
                    Using Compression = New GZipStream(MS, CompressionMode.Compress)
                        Compression.Write(Data, 0, Data.Length)
                        Compression.Flush()
                        Compression.Close()
                        Return MS.ToArray()
                    End Using
                End Using
            Catch ex As Exception
                Log.Error("Error trying to compress data", ex)
                Throw
            End Try
        End Function

Обновление 3: также добавлено больше кода Java.переменная in является возвращением InputStream из socket.getInputStream ()

Ответы [ 3 ]

1 голос
/ 10 августа 2010

Это, конечно, не должно быть связано с задействованными данными - потоки имеют дело с двоичными данными, так что вообще не должно быть шансов.

Однако, не видя ваш код, сложно сказать наверняка. Моим первым портом вызова было бы проверить, где вы используете InputStream.read() - проверить, правильно ли вы используете возвращаемое значение, вместо того, чтобы предполагать, что один вызов read() заполнит буфер.

Если бы вы могли предоставить код, это бы очень помогло ...

0 голосов
/ 10 августа 2010

Это не возможно.EOF в TCP поставляется как внеполосный сегмент FIN, а не через данные.

0 голосов
/ 10 августа 2010

Я подозреваю, что по какой-то причине данные изменяются в процессе работы, обрабатывая их как текст, а не как двоичные данные, поэтому это могут быть либо преобразования \ n, либо изменение кодовой страницы.

Как поток gzipped передается между двумя системами?

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