читать биты а не int из сокета - PullRequest
0 голосов
/ 24 июня 2009

Сторонняя программа позволяет мне запрашивать данные из его порта ip :. Я спрашиваю вещи через этот классический код. Вот конструктор моего класса соединения:

public TcpConnection(String adress, Integer port) {
    this.adress = adress;
    this.port = port;
    try {
        socket = new Socket(adress, port);
    System.out.println("Opening connection");
        out = new PrintWriter(socket.getOutputStream(), true);
        InputStream r = new DataInputStream(socket.getInputStream());
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    } catch (UnknownHostException e) {
        // TODO: handle exception
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Затем я читаю свой сокет с in.read() в цикле while.

Это позволяет мне читать сокет int через int, но мне нужна более детальная детализация. (Некоторая информация в ответе кодируется в 2 байта, некоторые в битах, некоторые в 64 байтах ....). Так что мне нужно прочитать 2 байта, а затем немного. затем еще один бит, затем 1 байт и проверьте каждый бит этого байта.

Сначала я подумал: «Хорошо, я конвертирую int в бинарное представление String», (через Integer.toBinaryString(whatIget)) но это просто глупо и подвержено ошибкам.

Я уверен, что что-то упустил для решения этой случайной проблемы. Есть идеи?

Edit2: я удаляю «когда я читаю int, я читаю 32 бита (4 байта)», потому что это неправильно, а не в этом вопрос. Таким образом, Reader.read () читает int, если этот метод читает только байт, он читает 1/4 int ??!?

Ответы [ 6 ]

4 голосов
/ 24 июня 2009

Нет. read () читает 8 бит / 1 байт за раз.

Вы можете получить байты, слова, int, long, строку utf-8 и т. Д. Из DataInputStream, если в дальнейшем будете использовать типизированную ссылку DataInputStream. Есть

DataInputStream r = new DataInputStream(socket.getInputStream());
r.readLong();
r.readShort();

вместо

InputStream r = new DataInputStream(socket.getInputStream());

Однако для слов int и long значение 'Endiannes' данных имеет значение. DataInputStream объединяет байты в формате с прямым порядком байтов, где ваши данные могут иметь формат с прямым порядком байтов. Возможно, вам придется поменять местами байты в коротком / int / long после чтения из DIS. Здесь Integer.reverseBytes () и его друзья пригодятся.

Если вам нужно получить данные размером в бит (например, прочитать 6 бит, затем 4, 12 и т. Д.), Вы можете проверить ответы на этот недавний вопрос .

Редактировать: Удалены 8 битов, поскольку это вводит в заблуждение в этом контексте.

Редактировать 2: Перефразируя мое 3-е предложение.

2 голосов
/ 25 июня 2009

Вы не можете прочитать только бит: сокет / TCP / IP работают с байтом как наименьшей единицей.
Вам нужно будет прочитать байт, содержащий бит, и использовать некоторое сдвиг / маскирование битов, чтобы получить значение одного бита:

int byte = r.read();
boolean bit1 = (byte && 0x01) != 0;  // first bit (least significatn)
boolean bit2 = (byte && 0x02) != 0;  // second bit
boolean bit3 = (byte && 0x04) != 0;  // thrid bit
...
1 голос
/ 24 июня 2009

Вы не должны использовать Reader (у вас есть BufferedReader) для такого рода данных. Из DataInputStream (который вы уже используете) вы можете получить Bytes, Ints или многие другие типы (с методами readByte и т. Д.). Одиночные биты, которые вы не можете получить, данные в потоках всегда не менее байта. Это не является ограничением, специфичным для Java, в других языках вы также можете читать как минимум байты из файлов Sockets и. Если вам нужны отдельные биты из этого, вам нужны логические операции для извлечения их из прочитанных вами байтов.

1 голос
/ 24 июня 2009

Вы должны использовать BufferedInputStream, чтобы читать. BufferedReader для текстовых данных.

read() читает по одному байту за раз.

Тебе не нужно об этом беспокоиться.

Каждый вызов read() возвращает один байт.

См. Javadocs для read() метода InputStream.

Считывает следующий байт данных из входного потока.

1 голос
/ 24 июня 2009

вы можете прочитать int по int и извлечь информацию через побитовые операторы

0 голосов
/ 24 июня 2009

Вы не можете прочитать отдельные биты из InputStream. Это невозможно, как вы можете видеть в определении API InputStream.read () .

Итак, заключите ответ в DataInputStream, и вы будете читать из него каждый кусочек информации, как указано в kd304.

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