Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Отслеживания потери сети socket / 15 сообщений из 15, страница 1 из 1
04.03.2016, 14:41
    #39185961
AlexSSS4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживания потери сети socket
Как-то странно получается. Клиент замечает, что связь с сервером потеряна, если я выключу сам сервер, а если я например, вырублю сеть на клиенте, то клиенту кажется, что сервер еще в сети. Проверял также на примерах из интернета. Вот один из них без потоков.
Код: 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.
public class Server {
   public static void main(String[] ar)    {
     int port = 6666; // случайный порт (может быть любое число от 1025 до 65535)
       try {
         ServerSocket ss = new ServerSocket(port); // создаем сокет сервера и привязываем его к вышеуказанному порту
         System.out.println("Waiting for a client...");

         Socket socket = ss.accept(); // заставляем сервер ждать подключений и выводим сообщение когда кто-то связался с сервером
         System.out.println("Got a client :) ... Finally, someone saw me through all the cover!");
         System.out.println();

 // Берем входной и выходной потоки сокета, теперь можем получать и отсылать данные клиенту. 
         InputStream sin = socket.getInputStream();
         OutputStream sout = socket.getOutputStream();

 // Конвертируем потоки в другой тип, чтоб легче обрабатывать текстовые сообщения.
         DataInputStream in = new DataInputStream(sin);
         DataOutputStream out = new DataOutputStream(sout);

         String line = null;
         while(true) {
           line = in.readUTF(); // ожидаем пока клиент пришлет строку текста.
           System.out.println("The dumb client just sent me this line : " + line);
           System.out.println("I'm sending it back...");
           out.writeUTF(line); // отсылаем клиенту обратно ту самую строку текста.
           out.flush(); // заставляем поток закончить передачу данных.
           System.out.println("Waiting for the next line...");
           System.out.println();
         }
      } catch(Exception x) { x.printStackTrace(); }
   }
}



Код: 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.
public class Client {
    public static void main(String[] ar) {
        int serverPort = 6666; // здесь обязательно нужно указать порт к которому привязывается сервер.
        String address = "192.168.1.170"; // это IP-адрес компьютера, где исполняется наша серверная программа. 
                                      // Здесь указан адрес того самого компьютера где будет исполняться и клиент.

        try {
            InetAddress ipAddress = InetAddress.getByName(address); // создаем объект который отображает вышеописанный IP-адрес.
            System.out.println("Any of you heard of a socket with IP address " + address + " and port " + serverPort + "?");
            Socket socket = new Socket(ipAddress, serverPort); // создаем сокет используя IP-адрес и порт сервера.
            System.out.println("Yes! I just got hold of the program.");

            // Берем входной и выходной потоки сокета, теперь можем получать и отсылать данные клиентом. 
            InputStream sin = socket.getInputStream();
            OutputStream sout = socket.getOutputStream();

            // Конвертируем потоки в другой тип, чтоб легче обрабатывать текстовые сообщения.
            DataInputStream in = new DataInputStream(sin);
            DataOutputStream out = new DataOutputStream(sout);

            // Создаем поток для чтения с клавиатуры.
            BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
            String line = null;
            System.out.println("Type in something and press enter. Will send it to the server and tell ya what it thinks.");
            System.out.println();

            while (true) {
                line = keyboard.readLine(); // ждем пока пользователь введет что-то и нажмет кнопку Enter.
                System.out.println("Sending this line to the server...");
                out.writeUTF(line); // отсылаем введенную строку текста серверу.
                out.flush(); // заставляем поток закончить передачу данных.
                line = in.readUTF(); // ждем пока сервер отошлет строку текста.
                System.out.println("The server was very polite. It sent me this : " + line);
                System.out.println("Looks like the server is pleased with us. Go ahead and enter more lines.");
                System.out.println();
            }
        } catch (Exception x) {
            x.printStackTrace();
        }
    }
}



Тут также, если я выключаю сеть, то клиент понимает, что связь с сервером потеряна. Но если я например, выключу сеть между сервером и клиентом, то ни клиент, ни сервер не понимают, что они потеряли связь. Что можно сделать?

Пробовал сделать, отправлять через каждые 5 минут, тестовый пакет, но он почему-то отправлялся раз, а клиент потом не отвечал на другие действия.

Я вот еще думал, проверять работоспособность сервера и клиента с помощью пинга на сервере, но будет ли это затратно, если клиентов будет штук 5? И, например, если клиент за это время, как потеряна связь, успеет перезагрузить машину, то это уже не является правильным решением.

Может быть кто-нибудь сталкивался и знает способ решения?
...
Рейтинг: 0 / 0
04.03.2016, 14:45
    #39185963
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживания потери сети socket
AlexSSS4Пробовал сделать, отправлять через каждые 5 минут, тестовый пакет,
правильно
а чтоб работало - баги поправить
...
Рейтинг: 0 / 0
04.03.2016, 14:47
    #39185969
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживания потери сети socket
Изопропилправильно
И при настроенном Keep Alive система это делает самостоятельно.
...
Рейтинг: 0 / 0
04.03.2016, 15:13
    #39185994
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживания потери сети socket
Dimitry SibiryakovИзопропилправильно
И при настроенном Keep Alive система это делает самостоятельно.
ненадёжно. неизвестно что на пути NAT и всякие xinetd с Keep Alive сделают
...
Рейтинг: 0 / 0
06.03.2016, 12:54
    #39186836
AlexSSS4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживания потери сети socket
Изопропил,

А если с этим тестовым пакетом, придет одновременно другой пакет. То как их отобрать?
...
Рейтинг: 0 / 0
06.03.2016, 13:04
    #39186843
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживания потери сети socket
AlexSSS4Изопропил,

А если с этим тестовым пакетом, придет одновременно другой пакет. То как их отобрать?
одновременно - ну никак не придут.

а служебные пакеты - в протоколе предусмотреть нужно, как ping-pong в websocket, например

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
Opcode:  4 bits

      Defines the interpretation of the "Payload data".  If an unknown
      opcode is received, the receiving endpoint MUST _Fail the
      WebSocket Connection_.  The following values are defined.

      *  %x0 denotes a continuation frame

      *  %x1 denotes a text frame

      *  %x2 denotes a binary frame

      *  %x3-7 are reserved for further non-control frames

      *  %x8 denotes a connection close

      *  %x9 denotes a ping

      *  %xA denotes a pong

      *  %xB-F are reserved for further control frames
...
Рейтинг: 0 / 0
06.03.2016, 15:46
    #39186904
AlexSSS4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживания потери сети socket
Изопропил,

А для проверки лучше сделать отдельный поток?
...
Рейтинг: 0 / 0
06.03.2016, 16:02
    #39186907
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживания потери сети socket
AlexSSS4,

какова собственно изначальная задача?
может и голый TCP применять не нужно, а стоит воспользоваться высокоуровневыми средствами?
...
Рейтинг: 0 / 0
06.03.2016, 16:43
    #39186924
AlexSSS4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживания потери сети socket
Изопропил, Задача отслеживать одновременный вход пользователя под одной учетной записи в домен. Если это не отслеживать, то пользователь остается в MultuHashMap, когда связь с севером была потеряна, но после восстановлена.
...
Рейтинг: 0 / 0
06.03.2016, 17:17
    #39186930
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживания потери сети socket
AlexSSS4,

при восстановлении связи - просто чистить коллекцию от мусора- не подойдёт?
...
Рейтинг: 0 / 0
06.03.2016, 17:26
    #39186932
AlexSSS4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживания потери сети socket
Изопропил, Не могу додуматься, как это воплотить в код
...
Рейтинг: 0 / 0
06.03.2016, 19:03
    #39186948
chabapok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживания потери сети socket
Лучше всего почитать, как вообще работает TCP протокол.
Он работает поверх IP, который представляет из себя негарантированную непоследовательную доставку пакетов. Поверх этого наворачиваются некоторые служебные данные, которые обеспечивают перевысылку потеряных пакетов - и это называется TCP.

Теперь вопрос - а как вообще можно понять, что соединение легло? Конечно, если это соединение напрямую точка-точка, то при обрыве провода железо может понять, что был обрыв. Но tcp был разработан для интернета, когда пакет проходит через несколько узлов. Если где-то там на пути затор - пакет не доходит до получателя.

И как получателю узнать - то ли пакет к нему не дошел, то ли не слался? А никак, по большому счету.
Но обычно делают таймауты. Если данных не было какое-то время, то считается что это обрыв. Сокет при этом надо закрыть, причем желательно жестким методом, с высылкой RST флажка. И протокол делают так, чтобы иногда что-то слалось.

Есть и другой способ - заводится понятие сессии, и она может переживать несколько переподключений.

Keep alive по умолчанию настроен на 4 часа, и менять эту настройку - это повлиять на всю ОС, а не на конкретный сокет. Довольно бесполезный механизм для пользователя. Больше системный, для подчистки ресурсов.
...
Рейтинг: 0 / 0
06.03.2016, 19:21
    #39186952
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживания потери сети socket
AlexSSS4а если я например, вырублю сеть на клиенте, то клиенту кажется, что сервер еще в сети
Если ты где-то вырубил сеть - то ты сам себе злобный буратино.
В правильных архитектурах ты должен послать управляющий сигнал
типа "node is down" через те-же прикладные протоколы. А на другом
конце - принимать соотв решение о ребуте или реконфигурации.

Периодический ping - в принципе правильный вариант. Только
надо уточнить что не везде в интернетах ICMP ходит. На каких-то
узлах (хозяин-барин) могут быть особые правила.
...
Рейтинг: 0 / 0
06.03.2016, 23:38
    #39187024
13-й Пилигрим
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживания потери сети socket
...
Рейтинг: 0 / 0
07.03.2016, 01:39
    #39187036
chabapok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживания потери сети socket
maytonВ правильных архитектурах ты должен послать управляющий сигнал
типа "node is down" через те-же прикладные протоколы. А на другом
конце - принимать соотв решение о ребуте или реконфигурации.

Если сеть положили - сигнал на тот конец не дойдет.
Тут именно надо посылать пинг, и ждать какое-то время ответа
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Отслеживания потери сети socket / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]