TheNerdFromYesterday
TheNerdFromYesterday

Reputation: 145

How I can send an String and an Integer over a socket?

I have 2 buttons in my client with a button listener each.

In my firt button listener I am sending a String over the socket and I am getting back an array of integers after it is spanwed. No problem there. Here is my code.

public void rollDice() {

    try {
        DataOutputStream sout1 = new DataOutputStream(socket.getOutputStream());
        String line = "dice";
        PrintStream out1 = new PrintStream(sout1);
        out1.println(line);
    } catch (UnknownHostException e1) {
        e1.printStackTrace();
    } catch (IOException e1) {
        e1.printStackTrace();
    }

}

With the second listener I want t send first a string to put the server into the right state, and after I want to send an integer to continue the process. Here is my code but it doesn't seem to work. Server is printing a random number, even if I send a "2".

public void sendDice() {

    try {
        DataOutputStream sout2 = new DataOutputStream(socket.getOutputStream());
        String line = "pick";
        PrintStream out2 = new PrintStream(sout2);
        out2.println(line);

        out2.write(diceListLength);
    } catch (UnknownHostException e1) {
        e1.printStackTrace();
    } catch (IOException e1) {
        e1.printStackTrace();
    }
}

Here is the server's side.

public void run() {

        boolean running = true;

        try {

            // Create streams for reading / writing lines of text to the socket
            DataInputStream input = new DataInputStream(s.getInputStream());
            DataInputStream inputInt = new DataInputStream(s.getInputStream());

            ObjectOutputStream output = new ObjectOutputStream(s.getOutputStream());

            // Print a message:
            System.out.println("\nClient from: " + s.getInetAddress() + " port " + s.getPort());

            while(running) {
                String st = input.readLine();

                if (st.equals("dice")) {
                    for (int i = 0; i < diceRolled.length - number; i++) {
                        diceRolled[i] = (int) ( 1 + Math.random() * 6);
                        System.out.print(diceRolled[i] + " ");
                    }
                    output.writeObject(diceRolled);
                    output.reset();
                } else if (st.equals("pick")) {
                    number = inputInt.readInt();
                    System.out.print(number);

                }
            } 
        } catch (IOException e) {
            System.out.println("Error: " + e.getMessage());
         // Always be sure to close the socket
        } finally {
            try {
                if (s != null) {
                    System.out.println(s.getLocalSocketAddress() + " closed.");
                    s.close();
                }                   
            } catch (Exception e) {
                System.out.println("Error: " + e.getMessage());
            }
        }
    }

Upvotes: 3

Views: 1159

Answers (1)

Oerd
Oerd

Reputation: 2303

Try setting autoFlush on the PrintStream when you create it... a single integer will not be sent until newline or buffer full.

From java's documentation

autoFlush - A boolean; if true, the output buffer will be flushed whenever a byte array is written, one of the println methods is invoked, or a newline character or byte ('\n') is written

Also useful:

  1. Use line-based messaging, i.e. the second message type can be "pick:4" (check with st.startsWith("pick")) and then parse the integer. With your code, you can easily end up loosing state. (Single-line messages are "pseudo-atomic").
  2. Don't create DataInputStreams in every listener method, make them object variables (same for PrintStreams...). There's no need to (re)create objects in every click.

Upvotes: 2

Related Questions