Я написал многопоточное приложение сокетов java-сервер-клиент с функцией обмена сообщениями, но столкнулся с проблемой одновременного ввода-вывода консоли.
Главная консоль сервера прослушивает ввод с клавиатуры и одновременно распечатывает сообщения от клиентов. На стороне клиента есть отдельная нить для распечатки.
Вот упрощенное представление кода:
public class ServerThread{
....
BufferedReader in = ... (sock.getInputStream);
while(true){
System.out.println(in.readline());
....
public class ServerMain{
.....
BufferedReader keyb = ... (System.in);
while(true){
in = keyb.readLine();
....
Проблема возникает, когда я что-то набираю в консоли главного сервера, и в то же время приходит сообщение от одного из клиентов.
Это сообщение затем заканчивается тем, что я печатал на экране, и курсор перемещается в начало следующей строки, ожидая ввода.
То, что было набрано ранее, застряло в буфере клавиатуры, и я больше не могу его редактировать. Та же проблема происходит на стороне клиента.
Вопрос в том, как я могу печатать сообщения на экране, не прерывая текущий ввод?
(введенный текст также должен оставаться напечатанным на экране, как в поведении readLine () по умолчанию)
Я уже попробовал некоторые из предложенных решений для других подобных проблем:
В библиотеках Lanterna и JCurses отсутствует поддержка собственных потоков System.IO. Мне бы пришлось заново изобретать колесо и реализовать его все самостоятельно вручную из памяти на экран, по одному символу за раз плюс создание целого слоя графического интерфейса консоли.
Другая вещь использовала коды ANSI , но я не мог понять, как с ними делать то, что мне нужно. Я мог бы читать по одному входному символу за раз вместо целой строки, затем, если пришло сообщение, очистить строку, переместить курсор в начало и распечатать, но потом в следующей строке я не знаю , как печатать ранее буферизованный текст и все еще иметь возможность удалять символы с возвратом .
изменить:
GUI не является опцией , так как я хочу, чтобы мой код мог работать на сервере без монитора.
(также предположим, что на каждой стороне будет работать только один терминал, консоль, оболочка и приложение) )