Предполагая, что вы хотите быть в состоянии иметь дело с «линий», я бы, вероятно, начать с чего-то вроде этого:
public class SocketReader implements Runnable {
private final InputStream stream;
private final Queue<String> destination;
private volatile boolean active = true;
private SocketReader(InputStream stream, Queue<String> destination) {
this.stream = stream;
this.destination = destination;
}
public static SocketReader getReader(Socket toRead, Queue<String> destination) throws IOException {
return new SocketReader(toRead.getInputStream(), destination);
}
public void shutdown() {
active = false;
}
public void run() {
while(active) {
if (stream.hasNextLine() && active) {
final String line = stream.nextLine;
destination.add(line);
}
}
try {
stream.close();
} catch (IOException e) {
// Log somewhere
}
}
}
Поместите это в свой поток (или как часть потока или пула исполнителей, действительно), и вы сделали остальную часть вашего приложения неблокирующимся в отношении этого кода. EXPECT это для блокировки при ожидании обновлений от stream.hasNextLine()
. Вы даже можете поставить BlockingQueue
, если вы не хотите активно опросить очередь, но обрабатываете обновления каким-либо другим способом.
Вы можете сделать что-то подобное для вывода:
public class QueuedPrinter implements Runnable {
private final Queue<String> input;
private final PrintStream destination;
private volatile boolean active;
public QueuedPrinter(Queue<String> input, PrintStream destination) {
this.input = input;
this.destination = destination;
}
public void shutdown() {
active = false;
}
public void run() {
while(active) {
final String line = input.poll();
if (line != null && active) {
destination.println(line);
}
}
}
}
Пожалуйста, обратите внимание, что я не проверял это, и вы, возможно, придется настроить вещи немного для других проверяемых исключений. Вероятно, вам нужно добавить дополнительный код проверки ошибок (наводит на мысль о нулевой обработке). Кроме того, это не полностью threadsafe, но, вероятно, будет «достаточно хорошим» для большинства целей.
Определить «застрял». Сокеты позволяют асинхронную связь? Где ваша внутренняя фраза 'catch', или какой смысл? Не отключайте все исключения - используйте только те, которые вы можете учитывать (за исключением самого высокого уровня приложения). Не используйте 'while (true)' - проверьте какое-то условие, поэтому цикл можно безопасно отключить; в настоящее время пользователю нужно будет убить поток через какой-то диспетчер потоков (скажем, TaskManager), а не приятную перспективу. –
Застревание Я имею в виду, что он не завершает цикл и ждет выхода из потока. Только при выходе от клиента цикл будет завершен. Я исправил инструкции try/catch, а цикл while (true) не является проблемой. – mudassir
Это говорит о том, что поток, возвращаемый из 'socket.getInputStream()', является «блокировкой», то есть он ожидает ввода. Вероятно, вам нужно выполнить одно из следующих действий: 1) обернуть поток, первоначально полученный в тот, который не будет блокировать 2) установить опцию 'TIMEOUT' для сокета (и уловить полученное исключение) 3) использовать потоки и очереди, чтобы остальная часть вашей программы может продолжаться независимо от состояния входного сокета (это, вероятно, лучший вариант и может быть несколько скомбинирован с другими). –