0

を使用して単純なサーバーを実装していますAsynchronousServerSocketChannel。テスト目的で、2 つのメッセージを送信して"hi"から"stackoverflow"切断する小さなクライアント プロトタイプを作成しました。サーバー側では、到着したメッセージを読み取り、標準出力に出力します。クライアントが実行されたとき、私は受け取ることを期待しています:

message [hi], bytecount 2
message [stackoverflow], bytecount 13

問題は、サーバーが読み取りコールバックを呼び出したときに両方のメッセージがすでに到着していることがあるため、

message [histackoverflow], bytecount 15

代わりは。

問題は、サーバー側でメッセージが個別に到着することを保証できるかどうかです。

クライアント接続を処理する私のCompletionHandlerプロトタイプは次のとおりです。

class CommunicationHandler implements CompletionHandler<AsynchronousSocketChannel, Void> {

    private final AsynchronousServerSocketChannel server;

    public CommunicationHandler(final AsynchronousServerSocketChannel server) {
        this.server = server;
    }

    @Override
    public void failed(Throwable ex, Void attachment) {}

    @Override
    public void completed(final AsynchronousSocketChannel client, Void attachment) {

        // handle client messages
        final ByteBuffer buffer = ByteBuffer.allocateDirect(Server.BUFFER_SIZE);
        final Session session = new Session();
        try {
            client.read(buffer, session, new CompletionHandler<Integer, Session>() {

                @Override
                public void completed(Integer byteCount, final Session currSession) {
                    if (byteCount == -1) {
                        return;
                    }
                    buffer.flip();
                    // TODO forward buffer to message handler (probably protocol?)
                    System.out.println("message [" + convertToString(buffer) + "], byteCount " + byteCount);
                    buffer.clear();
                    // read next message
                    client.read(buffer, currSession, this);
            }

            @Override
            public void failed(Throwable ex, final Session currSession) {}
        });
    }
    // accept the next connection
    server.accept(null, this);
}

ByteBufferStringの変換:

public static String convertToString(ByteBuffer bb) {
    final byte[] bytes = new byte[bb.remaining()];
    bb.duplicate().get(bytes);
    return new String(bytes);
}

テスト クライアントのプロトタイプを次に示します。

public class Client {

public final void start() {
    try (AsynchronousSocketChannel client = AsynchronousSocketChannel.open();) {

        Future<Void> connCall = client.connect(InetAddress.getByName("127.0.0.1"), 8060));
        connCall.get();
        // client is now connected
        // send greeting message
        Future<Integer> writeCall = client.write(Charset.forName("utf-8").encode(CharBuffer.wrap("hi")));
        writeCall.get();
//        Thread.sleep(5000L);
        writeCall = client.write(Charset.forName("utf-8").encode(CharBuffer.wrap("stackoverflow")));
        writeCall.get();
        client.close();
    } catch (IOException e) {
    } catch (InterruptedException ex) {
    } catch (ExecutionException ex) {
    }
}
4

1 に答える 1