user287474 user287474 - 1 year ago 54
Java Question

TCP Server in Java

Im having trouble with sending information from a client to server.
The output is supposed to be:

*Server: *

$> java TCPClient /serverIP/ 8080

User ID of the current client: rocky // should print this out but it doesn't



$> java TCPServer 8080

Type login to start

login //user input

FROM SERVER: Please log in with your user ID.

rocky //user input

Sent to server : rocky


But the server doesn't print that statement out, does it have to do with the buffer or streaming needing to be cleaned up? The code is included below.

TCPServer Code:

BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient =
new DataOutputStream(connectionSocket.getOutputStream());
outToClient.writeBytes("Please log in with your user ID.\n");
String clientId = inFromClient.readLine()
System.out.println("User ID of the current client: " + clientId);
outToClient.writeBytes("Game has started!\n");

TCPClient Code:

DataOutputStream outToServer =
new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
System.out.println("Type login to start");
if ((inFromUser.readLine()).equals(login))
System.out.println("FROM SERVER: " + inFromServer.readLine());
String option = inFromUser.readLine();
System.out.println("Sent to Server: "+ option);
//should print "FROM SERVER: Game has started!"
System.out.println("FROM SERVER: " + inFromServer.readLine());

Answer Source

You are mixing up character streams and byte streams. A DataOutputStream is typically used for sending non-character data. There are no field separators or line terminators, because the input should not be free form. An integer would be sent as exactly 4 bytes, not as a variable number of characters between \x0030 and \x0039. In contrast, a BufferedReader is used for line-oriented character data. Characters are encoded with a Charset such as ASCII or UTF-16. Lines are terminated with \n or \r\n depending on the platform.

For what it looks like you are trying to do, a PrintStream should be used instead of a DataOutputStream. Eg)

    PrintStream outToClient = new PrintStream(connectionSocket.getOutputStream(), true);
    outToClient.println("Please log in with your user ID.");

Use similar code for outToServer.

Note: the true value passed to the PrintStream constructor enables auto flushing when a newline is sent, so most #flush() calls become unnecessary.


For symmetry, because you are using BufferedReader, I should have said to use a PrintWriter. Drop in replacement; use in exactly the same way:

PrintWriter outToClient = new PrintWriter(connectionSocket.getOutputStream(), true);
outToClient.println("Please log in with your user ID.");

One final note: both PrintStream and PrintWriter suppress all IOExceptions. You should use #checkError() periodically to ensure an exception has not occurred, such as the stream closing.