Чтение из сокета не ждет ввода? - PullRequest
1 голос
/ 04 февраля 2009

Я пытаюсь заняться программированием на языке Socket на Java и использую метод BufferedStreamReader.read (char []).

Документ Java содержит:

Читает символы в массив. это метод будет блокироваться, пока не будет доступно, ошибка ввода-вывода или конец потока достигнут.

Только это не блокирует на входе.

Может ли кто-нибудь указать на проблему со следующим кодом? Даже со строкой, которая записывает в выходной поток, строка, которая печатает «RCVD:», печатает, но без данных после RCVD.

public class Main {

    /**
     * @param args the command line arguments
     */
         private static Socket tcpSocket;
    public static void main(String args[]) {
        try {
            tcpSocket = new Socket("localhost", 8080);
        } catch (UnknownHostException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

        new Thread(new Runnable() {

            public void run() {
                try {

                    System.out.println("Starting listening");

                    char[] dataBytes = new char[9];
                    BufferedReader netStream = new BufferedReader(new InputStreamReader(tcpSocket.getInputStream()));
                    while (true) {
                        netStream.read(dataBytes);

                        System.out.println("RCVD: " + String.copyValueOf(dataBytes));
                    }
                } catch (UnknownHostException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }).start();

        new Thread(new Runnable(){
            public void run() {
                System.out.println("Starting Writer");
               PrintWriter out = null;
                try {
                    out = new PrintWriter(tcpSocket.getOutputStream(), true);
                    for (int i = 0 ; i < 10 ; i++)
                    {
                      //  out.println("000000000");
                    }
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }).start();

    }
}

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ

Я пытался изменить номер порта, и приложение зависало, возможно, я подключаюсь к чему-то еще, работающему на машине.

Также я получаю постоянный поток байтов, все из которых являются пробелами по его виду.

Ответы [ 5 ]

1 голос
/ 04 февраля 2009

На самом деле вы подключаетесь к чему-то другому на своей локальной машине.

Глядя на приведенный выше код, выглядит так, как будто вы ожидаете получить во входном потоке сокета данные, которые вы записываете в его выходной буфер. Выглядит так, как будто вы думаете о гнезде как о длине трубки, с входным потоком на одном конце трубки и выходным потоком на другом конце.

Гнездо на самом деле является одним концом трубки, с входным потоком, позволяющим вам слышать, что происходит внизу, и выходным потоком, позволяющим вам "говорить" в трубку.

Возможно, я не совсем понимаю, что вас смущает ... Помогает ли вышеизложенное?

1 голос
/ 04 февраля 2009

Если вы считаете, что ваши чтения не блокируются, запишите результат метода чтения и распечатайте его. Если ваше предположение верно, оно должно быть нулевым.

int n = netStream.read(dataBytes);
System.out.println("Read " + n + " characters.");

В любом случае вам нужно знать, сколько символов было прочитано, чтобы вы могли правильно вызывать copyValueOf - в общем, только часть массива будет заполнена данными из последнего чтения. И, конечно же, возвращаемое значение сигнализирует об окончании потока (спасибо, Даррон!), Поэтому вам нужно обязательно проверить его.

1 голос
/ 04 февраля 2009

Вам нужно заглянуть в ServerSocket . Ваш Socket на данный момент не «слушает», он пытается подключиться к localhost: 8080, но на самом деле не слушает его!

0 голосов
/ 06 февраля 2009

Просто 2с на это. Я не специалист по сокетам, но когда я им пользуюсь, я склонен полагаться на что-то еще в следующей строке для чтения.

char[] dataBytes = new char[9];//tcpSocket.getReceiveBufferSize()

int result = 0;
while((result = is.read(inputData)) != -1)//check for eof, 
  //if(result > 0){//<- most probably the case anyways considering .read returned
  //display only what was received
    System.out.println("RCVD: " + String.copyValueOf(inputData,0,result));
  //}
}
0 голосов
/ 04 февраля 2009

Я запустил ваш код и могу получать и распечатывать данные с сервера. Протестируйте конец сервера, чтобы убедиться, что он работает правильно.

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