Java SocketChannel прочете съобщенията с неизвестна дължина

    SocketChannel channel = (SocketChannel) key.channel();

    ByteBuffer buffer = ByteBuffer.allocate(1024);
    int numRead = -1;
    try {
        numRead = channel.read(buffer);
        System.out.println("numRead: " + numRead);
    }
    catch (IOException e) { e.printStackTrace();}
    if (numRead == -1) {
        this.dataMap.remove(channel);
        Socket socket = channel.socket();
        SocketAddress remoteAddr = socket.getRemoteSocketAddress();
        System.out.println("Connection closed by client: " + remoteAddr);
        channel.close();
        key.cancel();
        return;
    }
    System.out.println("Got: " + new String(buffer.array(), "windows-1251"));

От сокета чете 1024 байта данни. В този случай всички съобщения се комбинират и последното съобщение не идва изцяло. Как да прочета данните в буфер преди разделителя за съобщения '|' ? Искам да получа всяко съобщение поотделно.


person user1221483    schedule 28.06.2012    source източник
comment
API на сокета прави това вместо вас. Тъй като в него вече е в буфер.   -  person Woot4Moo    schedule 28.06.2012
comment
ето едно добро четиво. github.com/robbiehanson/CocoaAsyncSocket/wiki/CommonPitfalls говори за това, което питате. библиотеката е за obj-c, но статията е за често срещани клопки с tcp/udp, така че е приложима   -  person owen gerig    schedule 28.06.2012


Отговори (2)


Зависи от протокола, но ако протоколът се основава на знак за разделител на съобщения, единствената ви възможност е да прочетете колкото можете, без да блокирате, след което да сканирате съдържанието, което сте прочели, за да намерите разделителя. Трябва да направите това в цикъл, докато връзката се затвори (или докато вашата страна реши да затвори връзката).

Разбира се, можете да прочетете няколко съобщения наведнъж и дори частични съобщения, така че трябва да сте сигурни, че се справяте с тези случаи адекватно.

person biziclop    schedule 28.06.2012
comment
За съжаление този метод не ме устройва - person user1221483; 28.06.2012
comment
Това е жалко, защото няма друг начин, който би бил значително по-различен. Ако протоколът беше различен, например ако всяко съобщение започваше със заглавка с фиксиран размер, която съдържа дължината на съобщението, щеше да има. - person biziclop; 28.06.2012

В TCP няма такова нещо като съобщение. Това е API за поток от байтове. Ако искате съобщения, трябва да ги внедрите сами, чрез разделител, двойка STX/ETX, префикс на думата за дължина, протокол за самоописание и т.н.

person user207421    schedule 28.06.2012