Code running stuck at scanner.hasNextLine()

2019-07-23 17:21发布

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.");

    }

}
  1. I start the server: java Server.java
  2. 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);
        }
    }

3条回答
该账号已被封号
2楼-- · 2019-07-23 17:58

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.

查看更多
甜甜的少女心
3楼-- · 2019-07-23 18:02

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.


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.

查看更多
▲ chillily
4楼-- · 2019-07-23 18:03

Had almost the exact same problem, after banging my head in the keyboard for a couple of hours, this is what saved me:

printWriter = new PrintWriter(socket.getOutputStream(), true);

The second parameter sets auto-flushing to true.

查看更多
登录 后发表回答