Чтение из сокета не ждет ввода?
Я пытаюсь сделать некоторое программирование 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 ответов
Вам нужно заглянуть в ServerSocket. Ваш Socket на данный момент не "слушает", он пытается подключиться к localhost:8080, но на самом деле не слушает его!
Если вы считаете, что чтение не блокируется, запишите результат метода read и распечатайте его. Если ваше предположение верно, оно должно быть нулевым.
int n = netStream.read(dataBytes);
System.out.println("Read " + n + " characters.");
В любом случае вам нужно знать, сколько символов было прочитано, чтобы вы могли вызвать copyValueOf
правильно - как правило, только часть массива будет заполнена данными из последнего чтения. И, конечно же, возвращаемое значение сигнализирует об окончании потока (спасибо, Даррон!), Так что вам нужно обязательно проверить его.
На самом деле вы подключаетесь к чему-то другому на своей локальной машине.
Глядя на приведенный выше код, выглядит так, как будто вы ожидаете получить во входном потоке сокета данные, которые вы записываете в его выходной буфер. Выглядит так, как будто вы думаете о гнезде как о длине трубки, с входным потоком на одном конце трубки и выходным потоком на другом конце.
Сокет фактически является одним концом трубки, с входным потоком, позволяющим вам слышать, что происходит внизу, и выходным потоком, позволяющим вам "говорить" в трубку.
Возможно, я не совсем понимаю, что вас смущает... Помогает ли вышеизложенное?
Просто 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));
//}
}
Я запустил ваш код и могу получать и распечатывать данные с сервера. Протестируйте конец сервера, чтобы убедиться, что он работает правильно.