Буфер объединен с другим буфером на сервере TCP Vert.x - PullRequest
0 голосов
/ 07 мая 2020

Я хочу отправлять команды на сервер по TCP. Я создал сервер, который получает Buffers сообщений. В клиенте отправляю 10 команд. Я не знаю, почему сервер читает Buffer непредсказуемым образом.

сервер:

@Slf4j
public class TcpServ {

    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        NetServer server = vertx.createNetServer();

        server.connectHandler(socket -> {
            log.debug("New connection established with: socket address {}", socket.remoteAddress());

            socket.handler(new MyHandler());

            socket.closeHandler(v -> {
                log.debug("The socket has been closed.");
            });
        });

        server.listen(8088, "localhost", netServerAsyncResult -> {
            if (netServerAsyncResult.succeeded()) {
                log.debug("Server is now listening on actual port: " + server.actualPort());
            } else {
                log.debug("Failed to bind!");
            }
        });
    }

    @Slf4j
    static class MyHandler implements Handler<Buffer> {

        @Override
        public void handle(Buffer event) {
            byte[] bytes = event.getBytes();
            log.debug("Received data: {}", new String(bytes));
        }

    }

}

клиент:

@Slf4j
public class TcpClie {

    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();

        NetClient client = vertx.createNetClient();

        client.connect(8088, "localhost", netSocketAsyncResult -> {

            log.debug("Connection established.");

            NetSocket socket = netSocketAsyncResult.result();

            for (int j = 0; j < 10; j++) {
                String s = "Command" + j;
                Buffer b = Buffer.buffer(s.getBytes());
                socket.write(b);
            }

            log.debug("Data sent.");

            socket.handler(buffer -> {
                log.debug("Recived data from server with size: " + buffer.length());
            });

        });

    }

}

Я получил один раз:

[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command0Command1Command2Command3Command4Command5Command6Command7Command8Command9

в другой раз:

[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command0
[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command1
[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command2
[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command3
[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command4Command5
[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command6Command7
[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command8
[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command9

Я ожидаю, что каждый раз, когда я использую socket.write() сервер получает Buffer. Ожидаемый результат должен быть:

[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command0
[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command1
[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command2
[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command3
[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command4
[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command5
[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command6
[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command7
[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command8
[vert.x-eventloop-thread-1] DEBUG TcpServ$MyHandler - Received data: Command9

1 Ответ

2 голосов
/ 07 мая 2020

Это не ошибка. TCP - это протокол низкого уровня, он не определяет, что такое запрос или команда , как это делает HTTP.

Вы должны определить свой собственный протокол приложения поверх TCP, который может быть таким простым, как добавление символа новой строки \n между ними или наличие фиксированного размера буфера для всех команд.

На стороне сервера вы можете затем использовать Vert.x RecordParser:

RecordParser parser = RecordParser.newDelimited("\n", h -> {
  System.out.println(h.toString());
});

parser.handle(Buffer.buffer("command0\ncomma"));
parser.handle(Buffer.buffer("nd1\nco"));
parser.handle(Buffer.buffer("mmand2"));

Результат:

command0
command1
command2
...