I try to make a little Server-Client connection.
They both have a Scanner and a PrintWriter, and they are writing to each other using a Socket's input and output stream.
Client.java:
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Client {
static ServerSocket serverSocket;
static Socket socket;
static PrintWriter printWriter;
static Scanner scanner;
public static void main(String[] args) throws UnknownHostException, IOException {
socket = new Socket("localhost", 13344);
scanner = new Scanner(socket.getInputStream());
printWriter = new PrintWriter(socket.getOutputStream());
printWriter.println("dataline 1");
printWriter.println("dataline 2");
printWriter.println("dataline 3");
printWriter.flush();
//Error!? => I never got the echo from server in output
while (scanner.hasNextLine()) {
String lineRead = scanner.nextLine();
System.out.println("From server" + lineRead);
}
socket.close();
scanner.close();
printWriter.close();
System.out.println("Client has quit.");
}
}
Server.java
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server {
static ServerSocket serverSocket;
static Socket socket;
static PrintWriter printWriter;
static Scanner scanner;
public static void main(String[] args) throws IOException {
serverSocket = new ServerSocket(13344);
System.out.println("Waiting for Client to connect");
socket = serverSocket.accept();
scanner = new Scanner(socket.getInputStream());
printWriter = new PrintWriter(socket.getOutputStream());
System.out.println("Client has connected!!");
while (scanner.hasNextLine()) {
String lineRead = scanner.nextLine();
System.out.println("From Client: " + lineRead);
}
//Error!? => This line never runs
System.out.println("Now sending echo to Client");
printWriter.println("Echo from server1");
printWriter.println("Echo from server2");
printWriter.flush();
socket.close();
printWriter.close();
scanner.close();
System.out.println("Server has quit.");
}
}
- I start the server: java Server.java
- I start the client: java Client.java
Server's output:
Waiting for client to connect
Client has connected!!
From Client: dataline 1
From Client: dataline 3
From Client: dataline 3
Client's output is empty, not a word on it.
As you can see Server's code termination stops AFTER it is read from Client's output stream, and Client's code termination stops BEFORE it could read from Server's output stream.
My question is: How this Scanner-PrintWrier communication works, how do i know if a printWriter printed BEFORE a scanner could read in a server-client connection like this? What i did wrong and why? How to use properly a scanner?
E D I T:
@T.C Do you mean like this? Now i got full output, both Server and Client are quit after they are sent and received data.
I modified like this:
String line = "";
while (!line.equals("#")) {
line = scanner.nextLine();
if (!line.equals("#")) {
System.out.println("From server" + line);
}
}
The
Scanner.hasNext*()
methods will block to wait for input to scan, so you can't use it to detect when the client has finished sending.Simplest way to solve this problem would be to have the client send a special string telling the server it's done sending.
I have already posted some samples on client-server communication with detailed description.
Please have a look at below post that might help you to understand it better.
Multiple clients access the server concurrently
Java Server with Multiclient communication.
Try with BufferedReader that contains ready() that tells whether this stream is ready to be read. A buffered character stream is ready if the buffer is not empty, or if the underlying character stream is ready.
You can try with InputStream#available() but it doesn't have read line method.
Go with the solution suggested by @T.C. but he is not provided any sample code on it. You can find in it my post.
Had almost the exact same problem, after banging my head in the keyboard for a couple of hours, this is what saved me:
The second parameter sets auto-flushing to true.