Разбор строки и преобразование встроенных значений в порядок байтов хоста в Java - PullRequest
0 голосов
/ 13 сентября 2011

У меня есть Java-клиент и C-сервер. I-сервер хочет отправить клиенту пакет данных, содержащий некоторую информацию в определенном порядке, как показано ниже:

char *buf = NULL;

if(!(buf = malloc(sizeof(char) * pkt_len)))
{
        printf("Could not malloc\n");
        return -1;
}

 memcpy(buf,      &pkt_type,     2);
 memcpy(buf + 2,  &pkt_len,      4);
 memcpy(buf + 6,  &more_to_come, 1);
 memcpy(buf + 7,  &fb_id,        8);
 memcpy(buf + 15, &match,        4);
 memcpy(buf + 19, el->name,  name_len);
 memcpy(buf + 19 + name_len, "\n\r",    2);

 if(send(clientSock, buf, pkt_len, 0) < 0)
 {
     printf("Can not write to socket %d\n", clientSock);
     return -1;
 }

Конечно, я записал все короткие, целые и длинные целые в порядок сетевых байтов, прежде чем записать их в буфер. Данные принимаются в виде строки клиентом Java. Моя проблема в том, как разобрать эту строку. Например, я хотел бы узнать способ считывания 2 байтов, которые указывают длину pkt, и приведение его к короткому порядку байтов хоста. Я знаю, что Java предоставляет метод для преобразования строки в массив байтов. Но что мне делать после того, как я получил массив байтов. Некоторый код для выполнения этой задачи будет признателен

Ответы [ 2 ]

0 голосов
/ 13 сентября 2011

Я предполагаю, что char здесь имеет длину один байт.

Вы можете использовать DataInputStream . В зависимости от ваших типов данных, что-то вроде следующего может помочь вам начать. Обратите внимание, что пример использует ASCII в качестве кодировки символов и не пытается быть эффективным в любом случае.

package grimbo.test.bytes;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;

public class BytesTest {
    public static void main(String[] args) throws IOException {
        // start setup test data
        byte[] msgStart = {
        /*pkt_type*/0, 1,
        /*pkt_len*/0, 0, 0, 1,
        /*more_to_come*/1,
        /*fb_id*/1, 2, 3, 4, 5, 6, 7, 8,
        /*match*/2, 2, 2, 2 };
        String name = "John Smith\n\r";
        byte[] nameBytes = name.getBytes("ASCII");
        byte[] msg = new byte[msgStart.length + nameBytes.length];
        System.arraycopy(msgStart, 0, msg, 0, msgStart.length);
        System.arraycopy(nameBytes, 0, msg, msgStart.length, nameBytes.length);
        // end setup test data

        DataInputStream in = new DataInputStream(new ByteArrayInputStream(msg));

        new BytesTest().read(in);
    }

    void read(DataInputStream in) throws IOException {
        // assuming pkt_type is an unsigned 2-byte value
        int pkt_type = in.readUnsignedShort();
        print(pkt_type);

        // assuming pkt_len is an unsigned 4-byte value
        // Java doesn't have those, so read a signed int and mask to a long
        long pkt_len = in.readInt() & 0xFFFFFFFFL;
        print(pkt_len);

        // assuming vanilla byte is ok for this, but Java bytes are signed, not unsigned
        byte more_to_come = in.readByte();
        print(more_to_come);

        // don't know the format of this, so left as bytes
        byte[] fb_id = new byte[8];
        in.readFully(fb_id);
        print(fb_id);

        // don't know the format of this, so left as bytes
        byte[] match = new byte[4];
        in.readFully(match);
        print(match);

        char[] nr = { '\n', '\r' };
        byte[] name = readUntil(in, nr);
        print(name);
        System.out.println(">" + new String(name, "ASCII") + "<");
    }

    private byte[] readUntil(DataInputStream in, /* stop reading when these chars are found */char[] terminate)
            throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int terminateIdx = 0;
        int input = -1;
        while ((input = in.read()) > -1) {
            if (input == terminate[terminateIdx]) {
                if (terminateIdx == (terminate.length - 1)) {
                    // we've found the termination sequence
                    byte[] buf = baos.toByteArray();
                    // - terminateIdx because we don't include the termination sequence
                    byte[] result = new byte[buf.length - terminateIdx];
                    System.arraycopy(buf, 0, result, 0, result.length);
                    return result;
                }
                terminateIdx++;
            } else {
                // no match, reset count
                terminateIdx = 0;
            }
            baos.write(input);
        }
        return baos.toByteArray();
    }

    private void print(long l) {
        System.out.println(l);
    }

    void print(byte[] bytes) {
        for (int i = 0; i < bytes.length; i++) {
            if (i > 0) {
                System.out.print(",");
            }
            System.out.print(bytes[i]);
        }
        System.out.println();
    }
}

И вывод:

1
1
1
1,2,3,4,5,6,7,8
2,2,2,2
74,111,104,110,32,83,109,105,116,104
>John Smith<
0 голосов
/ 13 сентября 2011

Ты имеешь в виду что-то подобное ?:

    char[] charArray = new char[2];
    charArray[0] = "a".charAt(0);
    charArray[1] = "b".charAt(0);

    String string = new String(charArray);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...