Приложение Java зависает на in.hasNext();

Я работаю над приложением Battleship swing, которое общается через сокеты.

private ServerSocket server;
private Socket connection;
private PrintWriter out;
private Scanner in;

Я делаю подключение и установку выходных и входных потоков

out = new PrintWriter(connection.getOutputStream(), true);
in = new Scanner(connection.getInputStream());

Затем пользователь нажимает на поле, которое, по его мнению, есть корабль, а координаты отправляются

public void sendXY(String cord)
{
    out.print(cord);
}

Затем вызывается метод, который ждет, пока приложение противников ответит, если есть судно или нет (true | false).

public void readHit()
{
    boolean k = true;
    while(k)
    {
        if(in.hasNext()) //<--app hangs at this line
        {
            Fields.hit = in.nextBoolean();
            k = false;  
        }
    }
}

Но когда я проверяю это, мое приложение зависает при первом вызове in.hasNext().

Ответ 1

Сканер ожидает токена, метод печати не отправляет полный токен, если шнур String не содержит какой-либо терминатор. Вместо этого попробуйте использовать println.

Ответ 2

Из JavaDoc https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#hasNext()

Возвращает true, если этот сканер имеет другой токен на своем входе. Этот метод может блокироваться, ожидая ввода для сканирования. Сканер не продвигается мимо какого-либо ввода.

Внутри источников мы можем найти это:

public boolean hasNext() {
    ensureOpen();
    saveState();
    while (!sourceClosed) {
        if (hasTokenInBuffer())
            return revertState(true);
        readInput();
    }
    boolean result = hasTokenInBuffer();
    return revertState(result);
}

Похоже, что метод блокирует, если исходный поток открыт и нет байтов. Попытайтесь найти другие альтернативы для решения этой проблемы. Вы можете попытаться создать новый поток для каждого клиента, который будет называть hasNext()

Ответ 3

Из javadoc:

Возвращает true, если этот сканер имеет другой токен на своем входе. Эта метод может блокироваться, ожидая ввода для сканирования. Сканер не продвигайтесь мимо любого ввода.

Ответ 4

Сначала вы можете проверить, есть ли байты в входном потоке соединения:

InputStream instream = connection.getInputStream();
in = new Scanner(instream);

Затем заменим

if(in.hasNext())

с

if (instream.available() > 0)