Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
 
2 / 2 / 1
Регистрация: 27.09.2013
Сообщений: 93
1

Когда будет выход из цикла? (Чат: клиент-сервер)

04.03.2016, 15:20. Просмотров 455. Ответов 9
Метки нет (Все метки)

Пытаюсь разобраться в примере кода по созданию сервера для чата:
Соединились с новым клиентом. Создали для него выходной поток. Создаем параллельный поток t для чтения сообщения с клиента и рассылки его всем другим клиентам. В конструкторе ClientHandler мы создали входной поток для чтения данных с клиента. А потом в run() зацикливаем чтение строки с этого потока.
И тут я не могу понять: цикл работает, пока есть что прочитать. Но если клиент молчит значит происходит выход из цикла? А если выход - тогда и конец работы run(), а следовательно конец работы потока t. А потом когда клиент опять пошлет сообщение - как сервер его примет если уже прекратил работу с ним?
Код:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class VerySimpleChatServer { 
    ArrayList clientOutputStreams; 
    
public class ClientHandler implements Runnable { 
    BufferedReader reader; 
    Socket sock; 
 
    public ClientHandler(Socket clientSocket) { 
        try { 
            sock = clientSocket; 
            InputstreamReader isReader = new InputstreamReader(sock.get!nputStream()); 
            reader = new BufferedReader(isReader); 
        } catch(Exception ex) {
            ex.printstackTrace();
        } 
    } // Закрываем конструктор 
 
    public void run() { 
        String message; 
        try { 
            while ((message = reader.readLine()) != null) {      //Когда выход из цикла?
            Systern.out.printin("read " + message); 
            tellEveryone(message); 
            } // Закрываем while 
        } catch(Exception ex) {
            ex.printstackTrace();
        } 
    } // Закрываем run 
}//Закрываем внутренний класс
 
public static void main (String[] args) { 
    new VerySimpleChatServer().go(); 
} 
    
public void go() { 
    clientOutputStreams = new ArrayList(); 
    try { 
        ServerSocket serverSock = new ServerSocket(5000); 
        while(true) { 
            Socket clientSocket = serverSock.accept(); 
            PrintWriter writer = new PrintWriter(clientSocket.getOutputStream()); 
            clientOutputStreams.add(writer); 
            Thread t = new Thread(new ClientHandler(clientSocket)); 
            t.start() ; 
            System.out.println("got a connection"); 
        } 
    } catch(Exception ex) { 
        ex.printstackTrace(); 
    } 
} // Закрываем go 
 
public void tellEveryone(String message) { ... }
 
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.03.2016, 15:20
Ответы с готовыми решениями:

не работает полностью сервер то есть не выводит когда клиент подключился когда вышел и не отправляет строку
import socket sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) host = '192.168.0.26'...

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

Чат клиент-сервер
Народ, у меня похожая проблема. Написал чат на JAVA, естественно есть одна часть єто клиент и...

Клиент-сервер чат
Всем доброго времени суток. Нужно организовать клиент-серверный чат через ServerSocket,...

9
65 / 64 / 15
Регистрация: 15.12.2013
Сообщений: 166
04.03.2016, 15:30 2
CyberGudvin,
Java
1
2
while(true) { 
            Socket clientSocket = serverSock.accept();
сервер всегда находится в режиме прослушивания. Если приконнектился новый клиент, он действительно читает до тех пор, по есть что прочитать
Java
1
  while ((message = reader.readLine()) != null)
если нет, while(true) все равно работает в методе go()
0
2 / 2 / 1
Регистрация: 27.09.2013
Сообщений: 93
04.03.2016, 15:35  [ТС] 3
Эрнесто, не понял. Так это что получается:
Сервер подключается к клиенту только ради того, чтобы принять от него одно сообщение. Разослать это сообщение всем другим и отключиться от него? А потом когда этот клиент еще раз напишет - опять его подключить и т.д. ...?
0
65 / 64 / 15
Регистрация: 15.12.2013
Сообщений: 166
04.03.2016, 15:41 4
CyberGudvin, сервер по факту не подключается и не отключается, он в этой цепочке пассивное звено. подключается клиент, а задача сервера быть всегда готовым это подключение принять и прочитать сообщение, если таковое есть.
0
2 / 2 / 1
Регистрация: 27.09.2013
Сообщений: 93
04.03.2016, 15:46  [ТС] 5
Эрнесто,
Цитата Сообщение от CyberGudvin Посмотреть сообщение
while ((message = reader.readLine()) != null) {
Systern.out.printin("read " + message);
tellEveryone(message);
} // Закрываем while
Зачем тогда цикл? Все равно будет только одно сообщение. Просто:
Java
1
2
3
4
5
6
7
...
message = reader.readLine();
if (message != null)){
    Systern.out.printin("read " + message); 
    tellEveryone(message); 
}
...
0
30 / 30 / 5
Регистрация: 21.03.2013
Сообщений: 381
04.03.2016, 16:51 6
CyberGudvin, после выхода из цикла поток закроется, а сокет будет открыт. При новом входе того же клиента создастся новый поток и цикл снова закрутится но сокет будет открыт, закрывайте сокеты сударь ведь это по крайней мере не прилично держать их открытыми.
0
2 / 2 / 1
Регистрация: 27.09.2013
Сообщений: 93
04.03.2016, 17:06  [ТС] 7
powowstal, моя не понимать.
Цитата Сообщение от CyberGudvin Посмотреть сообщение
ServerSocket serverSock = new ServerSocket(5000);
Этот сокет вы имеете ввиду? я пробовал после цикла в методе go() вызвать у него close(), но он ругается: "Unreachabel statement!"
Да и зачем его закрывать? Нам ведь нужно чтобы он всегда пассивно работал принимал клиентов. Разве нет?
0
30 / 30 / 5
Регистрация: 21.03.2013
Сообщений: 381
04.03.2016, 19:03 8
CyberGudvin, нет милейший вы путаете сокеты с потоками. Вас нужно закрывать sock.close(); - это закрывает канал с пользователем который заходил, а ServerSocket serverSock = new ServerSocket(5000); - срверный сокет на 5000-м порту его трогать не нужно. Закрывать их нужно потому что они могут закончится если будут заходить новые пользователи + безопасность, еже ли вам нужно держать сокет открытым пока пользователь не покинут чат, нужно дописать команду которая его закроет при выходе с сервера.
0
2 / 2 / 1
Регистрация: 27.09.2013
Сообщений: 93
04.03.2016, 20:52  [ТС] 9
powowstal, кажется понял.
Кстати в книге откуда я взял этот код говорится, что: "... код работает, но сломать его можно сотней различных способов. Попробуйте сделать его более надежным."
Вы это имели ввиду? Если я буду закрывать соке после выхода каждого клиента - этого будет достаточно чтобы сделать его надежным? Если нет - то что еще необходимо сделать?
0
30 / 30 / 5
Регистрация: 21.03.2013
Сообщений: 381
06.03.2016, 22:44 10
CyberGudvin, Действительно есть куча способов взлома самое элементарное отсутствует проверка пользователя (логин-пароль) 2 по открытому сокету можно зайти на сервак даже если отключить порт, сервер упадет если забить оперативку короче тут их не пересчитать
вот толковая статья http://javatutor.net/books/tiej/socket
Советую покопать в сторону мультиплексирования
Тут советовали использовать node js + socket.io но это яваскрипт, но там все готовое
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.03.2016, 22:44

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

Клиент-сервер чат на C++/C#
Здравствуйте, написал клиент-серверный чат, клиент на c#, сервер на консольном с++, но с winapi...

Клиент-сервер чат на C++/C#
Здравствуйте, написал клиент-серверный чат, клиент на c#, сервер на консольном с++, но с winapi...

Чат клиент-сервер на сокетах
и все таки появилась еще одна проблема раньше все сообщения от клиентов просто оставались на...

Клиент-сервер для чат-а
Привет всем. Я лично перешел на Qt, но у меня шас конкретная задания в билдер. Как можно...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.