Java: невозможно записать в сокет после сокета in.readLine () - PullRequest
0 голосов
/ 21 декабря 2018

Я обращаюсь к вам, StackOverflow, на этом я упираюсь в стену.

Я занимаюсь программированием сокетов и вижу, когда я помещаю out.println ("... ") строка кода ДО цикла while (in.readLine ()) она работает правильно, но мне нужно, чтобы он был внутри цикла.

Чтобы было ясно, я не вижу никаких ошибок.Я просто не вижу текст на клиентской стороне этого приложения.Похоже, что это работает, но это не так.Кроме того, я не контролирую и клиентскую часть этого, он обрабатывается устройством, которое подключается через TCP к этому приложению Socket Listener.Возможно ли, что он разорвет соединение, как только будут прочитаны данные?

public class ConnectionHandlerTCP implements Runnable
{
        private final Socket clientSocket;

        ConnectionHandlerTCP(Socket socket)
        {
                clientSocket = socket;
        }

        public void run()
        {
                int uniqueId = 0;
                try (
                        BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream()));
                        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
                ){
                        String inputLine;

                        // This Line WORKS, I see it appear on the other side of the connection.
                        Log.debug("Sending now A");
                        out.println("text to send here");

                        while ((inputLine = in.readLine()) != null)
                        {
                                // This Line DOES NOT WORK, I do not see it on the other side of the connection.
                                //Log.debug("Sending now B");
                                //out.println("text to send here");

                                // ... bunch of commented out code here
                        }

                        in.close();
                        out.close();
                        clientSocket.close();
                } catch (IOException e) {
                        Log.error("Exception caught when trying to read input.", e.getMessage());
                } catch (Exception e) {
                        Log.error("Exception caught when trying to parse data.", e.getMessage());
                }
        }
}

Любая помощь будет принята с благодарностью.В случае, если это полезно, вот основной класс.

import java.net.*;
import java.io.*;

public class SocketListenerTCP 
{
    public static void main(String[] args) throws IOException {

        if (args.length != 1) {
            System.exit(1);
        }

        int portNumber = Integer.parseInt(args[0]);

        while(true)
        {
            try ( 
                ServerSocket serverSocket = new ServerSocket(portNumber);
            ) {

                Socket clientSocket = serverSocket.accept();

                new Thread(new ConnectionHandlerTCP(clientSocket)).start();

            } catch (IOException e) {
                Log.error("Exception caught", e.getMessage());
            }
        }
    }
}

Я немного упростил его, полностью вынул цикл, и он все еще работает неправильно.

                inputLine = in.readLine();
                Log.debug(inputLine);  

                Log.debug("Sending now");
                out.println("text to send here");

Ответы [ 3 ]

0 голосов
/ 21 декабря 2018

Код внутри

while ((inputLine = in.readLine()) != null)

, скорее всего, не работает, поскольку in.readLine продолжает ожидать ввода от клиента.

Клиентская программа / сокет должна иметь что-то на PrintWriter и println, чтобы ваш цикл while мог прочитать его и ответить (при условии, что это то, что вы намереваетесь достичь).

0 голосов
/ 22 января 2019

Ну, думаю, я наконец понял суть моей проблемы.Прежде всего, чтобы объяснить мою первоначальную проблему.Теперь я убежден, что устройство, к которому я подключаюсь, отключается от моего серверного приложения после 20 секунд (или около того) отсутствия чтения / записи.Таким образом, readline () будет ждать, пока эти 20 сработают, затем вернет все, что имеет, и в это время запись на устройство не будет разрешена.Однако, если я читаю все символы по одному (через read ()), он работает просто отлично, позволяет мне прочитать сообщение целиком и ждет последней итерации чтения цикла цикла read () для финала "-1 ", чтобы пройти, сигнализируя об окончании полезной нагрузки.Между этим временем (чтение первого символа и ожидание последнего символа) я анализирую полезную нагрузку и отправляю на устройство все, что захочу.Который по большей части получает.

Моя вторичная проблема заключалась в том, что иногда выходные потоки казались отключенными и никогда не позволяли мне больше отправлять сообщения.В исходном коде я заставил класс реализовать «Runnable».Это была ошибка.Я видел повсюду, что использование Runnable было предпочтительным способом сделать это, но я заметил, что OutputStream будет редко работать в этом случае, я переключился на расширение класса Thread, и он работает почти 100% времени.Я полагаю, что один поток перезаписывал выходной поток другого, затем следующий поток делал то же самое, а затем каждый из потоков не мог обмениваться данными через выходной поток.

После просмотра некоторых другихПримеры в Интернете, я предполагаю, что есть какой-то способ, которым я мог бы использовать Runnable, если бы захотел, но мне пришлось бы реорганизовать некоторые другие элементы в моем приложении.Мне придется еще кое-что почитать, прежде чем я вернусь по этому пути.

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

0 голосов
/ 21 декабря 2018

Чтение InputStream сокетного соединения является блокировкой потока.Вы не можете читать и писать одновременно в одной теме.Переместите Printwriter в другой поток, и все будет в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...