Тренируюсь работать с потоками ввода и вывода в Socket'ах. То есть со стороны клиента по нажатию кнопки у меня создаётся поток, который создаёт строку и выводит её в полученный из Socket'а OutputStream. После этого в цикле while() я жду ответа от сервера.
Вот этот код:
new Thread(() -> {
try {
socket = new Socket();
socket.connect(new InetSocketAddress("127.0.0.1", DEFAULT_PORT));
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
String str = "/reg/ %" + fieldName.getText() + "%" + fieldPassword.getText()+"%";
BufferedWriter writer = new BufferedWriter(new PrintWriter(os, true));
writer.write(str);
writer.flush();
int suc = 0;
while((suc = is.read()) != -1) {
if (suc == 1) {
area.setText("You was successfully registered!");
}else if(suc==0){
area.setText("Your login is already used!");
} else {
area.setText("Error connected");
}
}
}catch (SocketException exception)
{ exception.printStackTrace(); }
catch (IOException exception)
{ exception.printStackTrace(); }
}).start();
});
Со стороны сервера я жду соединения, для каждого соединения создаю новый поток, считываю первые 5 байтов - информация о последующей строке. В данном случае он получает строку "/reg/" и спрашивает, если метод register = true,то пишет 1 - удача, иначе 0 - неудача.
Вот код:
private void manage(Socket uSocket){
manageThread = new Thread(() -> {
long id = getID();
try {
byte[] tokenBytes = new byte[5];
InputStream is = uSocket.getInputStream();
OutputStream os = uSocket.getOutputStream();
is.read(tokenBytes);
String token = new String(tokenBytes);
switch (token){
case "/mes/":
break;
case "/reg/":
System.out.println("В блоке рег");
if(register(new BufferedReader(new InputStreamReader(is)), id)){
os.write(1);
}else{
os.write(0);
}
break;
case "/log/":
break;
}
}catch (IOException e) {
e.printStackTrace();
}
clientSockets.put(id, userSocket);
}, "manageThread");
manageThread.start();
}
Метод register здесь в третьей строке сервер просто зависает, скорей всего из-за метода is.readLine() :
private boolean register(BufferedReader is, long id) throws IOException{
System.out.println("В регистере");
String[] data = is.readLine().split("%");//В этом месте сервер зависает
System.out.println("В регистере прочитал");
try(ManageDatabase database = new ManageDatabase()){
if(!database.checkLogin(data[1])){
System.out.println("Проверил");
return false;
}
clients.put(id, new Person(data[1], data[2], id));
database.addUser(data[1], data[2], id);
}catch (IOException e){}
is.close();
return true;
}
Мне надо, чтобы он считывал эту строку и далее выдавал либо true либо false, дальше OutputStream бы записывал это и Client принимал успех или неудача, что изменяло бы TextArea, но видимо эти потоки ввода-вывода ждут друг друга.
Подскажите, что делаю неправильно, буду рад любой помощи.
Согласно документации метод readLine читает поток до тех пор, пока ему не встретится символ \r или \n (или оба: \r\n). Вы же эти символы от клиента не передаёте, поэтому метод на сервере всё ждёт и ждёт.
Вариантов тут есть как минимум два:
\n. Изменения в этом случае в коде будут минимальны: можно прямо вместо ненужного + "%" в конце строки кода написать + "\n"\n не придётся (но и метод в этом случае нужно использовать не readLine)Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости