0
votes

I'm designing a communications system for my project. However, I'm having some trouble handling packets. My communications system is written in java.net using ServerSocket, Socket, BufferedReader, and PrintWriter.

Currently, my system listens for packets every 500ms. It handles the login packet fine but it fails to handle the post-login packets(send id, disconnection). Every 500ms, I need my server to listen for login and post-login packets(send id, disconnection). How would I design a method that would detect and process post-login packets? The login packet consists of the handshake code, username, and password. Post-login packets (print id, disconnection) consist of the handshake code, user id, event id and other event parameters.

Packets are sent and received as a line of text using bufferedreader and printwriter.

This is my server sided decoder

    protected void decode(Socket server) throws Exception {
    final BufferedReader reader = new BufferedReader(new InputStreamReader(server.getInputStream()));
    final int handshake = Integer.parseInt(reader.readLine());
    if (handshake == LOGIN) {
        final Session session = new LoginSession(server, reader);
        session.read(-1);
    } else if (handshake == POST_LOGIN) {
        final int index = Integer.parseInt(reader.readLine());
        final int opcode = Integer.parseInt(reader.readLine());
        final Session session = store.get(index).getSession();
        session.reader = reader;
        session.read(opcode);
    }

}

@Override
public void run() {
    Socket server;
    try {
        server = serverSocket.accept();
        server.setTcpNoDelay(false);
        decode(server);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

These are my client -> server packets

    public void sendLogin() {
    write.write("100");
    write.write('\n');
    write.write("raees2");
    write.write('\n');
    write.write("LOL2");
    write.write('\n');
    write.flush();
}

public void sendPrintId() throws NumberFormatException, IOException {
    final BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
    final int id = Integer.parseInt(reader.readLine());
    System.out.println(id);

    write.write("101");
    write.write('\n');
    write.write(Integer.toString(id));
    write.write('\n');
    write.write(Integer.toString(0));
    write.write('\n');
    write.write(Integer.toString(10003));
    write.write('\n');
    write.flush();
}

public void sendDisconnection() throws NumberFormatException, IOException {
    final BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
    final int id = Integer.parseInt(reader.readLine());
    System.out.println(id);

    write.write("101");
    write.write('\n');
    write.write(Integer.toString(id));
    write.write('\n');
    write.write(Integer.toString(1));
    write.write('\n');
    write.flush();
}
1
Please do not vandalize your posts, which are licensed to Stack Overflow under CC by-SA. - TylerH

1 Answers

1
votes

Basically, you just need a loop to keep reading from the stream until the conversation is done. Right now, it reads one message and terminates.

I'm not sure how your protocol works, but something like this could give a starting point:

protected void decode(Socket server) throws Exception {
    final BufferedReader reader = new BufferedReader(new InputStreamReader(server.getInputStream()));

    /*
     * Somewhere in this loop, detect your protocol's termination condition
     * and break out.
     */

    for (;;) {
        final int handshake = Integer.parseInt(reader.readLine());
        if (handshake == LOGIN) {
            final Session session = new LoginSession(server, reader);
            session.read(-1);
        } else if (handshake == POST_LOGIN) {
            final int index = Integer.parseInt(reader.readLine());
            final int opcode = Integer.parseInt(reader.readLine());
            final Session session = store.get(index).getSession();
            session.reader = reader;
            session.read(opcode);
        }
    }
}

If you need to handle multiple connections at the same time, you will probably want your acceptor thread to start a new client thread for every connection successfully connected, as decode will block as it waits for the next messages.