Перенос типов данных uintN из C в Java (Socket Programing) - PullRequest
2 голосов
/ 23 октября 2011

У меня есть требование отправлять данные из собственной программы, написанной на C, через Sockets, а именно интерфейс winsock. Эти данные затем получаются программой Java. Java-программа получает пакет данных, для которого она знает порядок и выполняет некоторую обработку. Он принимает int, полученный из socket.Read () как client_socket.getInputStream().read()

Обработка этих int-данных, возвращаемых из Read (), анализируется для получения ожидаемых типов данных. В основном это нарезка полученных данных. Я могу только предположить, что функции read () читают 4 байта за раз (32-битный размер Java). Итак, я продолжаю разделять эти 4 байта (8 битов, а не тип Java) на 4 шорты Java, чтобы я мог правильно представить значения без знака, которые они представляют. После того, как у меня есть 4 шорта, если я знаю, что хочу, например, uint16, я просто объединяю 2 шорта

Проблема в том, что где-то я делаю неправильные манипуляции с битами, которые не работают так, как я думал. Код C и код Java приведены ниже, и он действительно прост, хотя он не работает. Вывод - это то, что я не могу понять, почему это так.

0 0   0 0    0 1     0 0     0 2     0 0     0 3     0 0     0 4 {...}

Код C отредактировал часть инициализации:

uint16_t buffer[255] = {};
uint16_t *current_pointer = buffer;
for(uint16_t index = 0; index < 255; index++) {
    *current_pointer = index;
    current_pointer++;
}
Write(client_socket, (char *)buffer, sizeof(buffer));

Код Java также отредактирован:

public final short[] JavaIntToUint8Array(int unsigned_int) {
    return new short[] { (short)((unsigned_int & 0xFF000000L) >> 24),
                (short)((unsigned_int & 0x00FF0000L) >> 16),
                (short)((unsigned_int & 0x0000FF00L) >> 8),
                (short)((unsigned_int & 0x000000FFL))};
}
public final int[] JavaIntToUint16(int unsigned_int) {
    short uint8_array[] = JavaIntToUint8Array(unsigned_int);
    return new int[] { (int)(uint8_array[0] << 8) | (int)uint8_array[1],            
        (int)(uint8_array[2] << 8) | (int)(uint8_array[3]) };
}

...

while (index < 255) {
        read_data = data_input.read();
        System.out.print(" ");
        System.out.print(JavaIntToUint16(read_data)[0]);
        System.out.print(" ");
        System.out.print(JavaIntToUint16(read_data)[1]);
        System.out.print("\t");
        index++;

}

Ответы [ 2 ]

3 голосов
/ 23 октября 2011

Я могу только предположить, что функция read () читает 4 байта за раз (32-битный размер Java)

Нет, вы не можете этого допустить. Документация для InputStream.read() гласит:

публичная аннотация int read () выдает IOException

Считывает следующий байт данных из входного потока. Значение byte возвращается в виде целого числа в диапазоне от 0 до 255. Если байт недоступен поскольку достигнут конец потока, значение -1 вернулся. Этот метод блокирует, пока не будут доступны входные данные, конец поток обнаружен или сгенерировано исключение.

A subclass must provide an implementation of this method.

Returns:
    the next byte of data, or -1 if the end of the stream is reached.
1 голос
/ 23 октября 2011

Самый простой подход к чтению беззнаковых коротких чисел состоит в использовании DataInput.readUnsignedShort ().

DataInputStream dis = new DataInputStream(data_input);
int num = dis.readUnsignedShort();

Используется порядок с прямым порядком байтов или порядковый номер сети. Если вы используете байты с прямым порядком байтов (например, на процессоре x86 / x64), вы можете изменить порядок байтов самостоятельно или использовать ByteBuffer для этого.

// using NIO
SocketChannel sc = SocketChannel.open(new InetSocketAddress("localhost", 12345));
ByteBuffer bb = ByteBuffer.allocateDirect(32*1024).order(ByteBuffer.LITTE_ENDIAN));
while(sc.read(bb) >= 0) {
    bb.flip();
    while(bb.remaining() > 1) {
       int num = bb.getShort() & 0xFFFF;
    }
    bb.compact();
}

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

...