Надежное Java Socket Программирование - PullRequest
0 голосов
/ 28 января 2012

Мое клиентское приложение должно быть в состоянии восстановиться в нескольких ситуациях. Когда питание включено, клиент считывает адрес и порт из файла и пытается подключиться к серверу. Если это первый раз, когда этот клиент используется на этом хосте, используется IP-адрес по умолчанию, но это может быть неверно. Затем пользователю необходимо ввести правильный IP-адрес. Порт жестко закодирован. Теперь он работает за одну секунду. Таймер пытается получить статус сервера ...

statusTimer = new Timer(ONE_SECOND, new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        final byte GET_STATUS = 20;
        SendCommand(GET_STATUS, null);
    }
});
statusTimer.start();

Если соединения нет, пользователю предлагается подключиться ...

private void SendCommand(byte command, byte[] parameters) {
    if ((null == socket) || (null == outputStream) || socket.isClosed())
        if (JOptionPane.YES_OPTION == 
            JOptionPane.showConfirmDialog(null, "Connect?")) 
            Connect();
            ...

private void Connect() {
    String s = (String) 
        JOptionPane.showInputDialog(null, "Enter IP Address", ipAddress);
    if (validateIp(s)) {
        ipAddress = s;
        connectTask = new ConnectTask();
        connectTask.start();
        ...

Сокет открыт, настроены потоки ввода-вывода и запущен RxThread.

class ConnectTask extends Thread {
    @Override public void run() {
        try {
            if (null == socket) socket = new Socket(ipAddress, TCP_PORT);
            if (null == outputStream) outputStream = socket.getOutputStream();
            if (null == inputStream) inputStream = socket.getInputStream();
            if (null == rxThread) rxThread = new RxThread();
            ...

Есть несколько плохих вещей, которые могут произойти в этот момент, например:
1. Сервер может быть выключен, когда клиент включен. Как лучше всего автоматически открыть сокет, настроить потоки ввода-вывода и продолжить работу при включении сервера?
2. Таким же образом сервер может увидеть цикл питания во время чтения, записи или ни того, ни другого. Есть ли хороший способ автоматического восстановления после восстановления питания?
3. Возможно, потребуется исправить IP-адрес, как указано выше.
Было бы неплохо справиться с этими и другими ситуациями, не требуя от пользователя закрытия и открытия клиентского приложения или выключения питания системы. Какие подходы необходимы для пуленепробиваемого сокета Java-клиента?
Этот и этот похожи, но имеют дело с серверными сокетами

1 Ответ

1 голос
/ 28 января 2012

Вы должны иметь возможность различать первое использование (когда данные сервера могут быть неверными, и пользователь должен получить запрос) и последующее использование (когда сервер может просто не работать).Вы можете сохранить файл, когда пользователь впервые вводит IP, например.

После этого вы, вероятно, захотите что-то вроде: внутреннего цикла, в котором вы пытаетесь подключиться к серверу и прочитать данные с тайм-аутом.Если сокет закрыт из-за сетевой ошибки, это можно перехватить с помощью блока try-catch.Поместите все это во внешний цикл, чтобы вы попробовали еще раз при отключении.

В зависимости от деталей и при условии, что объем данных невелик, вашему клиенту может быть проще всего открывать соединение каждый раз, когдачем пытаться поддерживать соединение, то переходите в спящий режим между соединениями.

Если сервер не отвечает, ваш текущий код (который создает новый поток ConnectTask каждую секунду с использованием таймера) может закончиться созданием нескольких ConnectTasks, один из которых созданв секунду, каждый пытается соединиться параллельно, хотя это трудно определить из кода, который вы опубликовали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...