Продолжайте сталкиваться с проблемами переменных класса в моем коде - PullRequest
0 голосов
/ 09 января 2019

Я немного поиграюсь с Java, начал делать клиент на Java-коде для небольшого приложения на основе чата. Я пытаюсь сделать переменную ssocket переменной класса, и это будет переменная, которая соединяется с сервером (еще не написала, но это не проблема). Итак, я объявляю переменную класса ssocket прямо под объявлением класса, а затем (я продолжаю делать и комментирую это) объявляю ssocket как пустой сокет в конструкторе. Затем в методе с именем sendToSever я пытаюсь сослаться на него, чтобы задать хост, порт и прочее, но он продолжает говорить, что он должен быть локальной переменной, а не переменной класса. Но, несколько строк позже в том же методе, я ссылаюсь на это нормально. Кроме того, когда я попытался установить ssocket для хоста и порта в конструкторе в блоке try, он также не использовал переменную класса. Я хочу официально установить сокет в sendToSever, чтобы они могли пытаться переподключаться каждый раз, когда выполняют какое-либо действие, но я не могу понять, как это исправить. Если что-то не понятно, я с удовольствием отредактирую этот пост.

Я пробовал:

  1. Настройка на статический
  2. Полное определение ssocket в конструкторе (назначение ему реального хоста и порта)
  3. Ссылка на сокет вне блока try, но все еще внутри sendToServer();

Я хочу объявить ssocket как переменную класса, а затем установить ее, если она еще не установлена ​​в sendToServer (так что, если она не может подключиться, переменная все еще равна нулю или что-то еще, а затем в следующий раз, когда она вызывается, она пытается восстановить соединение).

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import java.awt.Font;
// ...
import java.awt.event.ActionEvent;

public class ClientGUI extends JFrame {

    private JTextField lgntxtUsername;
    private JPasswordField lgntxtPassword;
    private JLabel lgnlblUsername;
    private JLabel lgnlblPassword;
    private JPanel SignupPanel;
    private JLabel lgnlblMAKE;
    private JLabel sgnlblImage;
    private JLabel sgnlblUsername;
    private JTextField sgntxtUsername;
    private JLabel sgnlblPassword;
    private JPasswordField sgntxtPassword;
    private JLabel sgnlblCNFPASS;
    private JPasswordField sgntxtPasswordC;
    private JButton sgnbtnSIGNUP;
    private Socket ssocket;

    // I declare the class variable above
    public ClientGUI() throws IOException {
        // define some JFrame stuff, skipping it
        // set to empty socket, though I have tried fully setting it in a try block, hadn't worked
        ssocket = new Socket();

    // More methods, don't use ssocket at all
    public int sendToServer(String text) {
        try (
            // Says it needs a declaration, doesnt register this as the class variable
            socket = new Socket("127.0.0.1", 123456);
            // Despite the error in the above line, I reference ssocket fine in the next few lines
            PrintWriter out = new PrintWriter(ssocket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(ssocket.getInputStream()));) {
            out.println(text);
            return 200;
        } catch (Exception e) {
            System.out.println(e.toString());
            String[] splitArray = e.toString().split(":");
            System.out.println(Arrays.toString(splitArray));
            return 500;
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Я заметил несколько проблем в коде и сделал следующие изменения.

  1. Сделать переменную ssocket уровнем класса
  2. Нет необходимости инициализировать его нулем внутри конструктора
  3. sendToServer проверит, является ли он нулевым, перед его инициализацией (в этом методе была опечатка)
  4. Как уже упоминалось @xtratic, конструктор закрыт неправильно.

Ниже приведен модифицированный код.

// static variable, single reference is shared across all instances of the class
private static Socket ssocket = null;

public ClientGUI() throws IOException {
    // ssocket is not initialized here
}

public int sendToServer(String text) {
    try (

        if (ssocket == null) {
            // typo, socket is used in code instead of ssocket 
            ssocket = new Socket("127.0.0.1", 123456);
        }
        // ...
    } catch (Exception e) {
        // if connectivity issue occurred, you can close the ssocket and set to null here
        // ...
    }
}

Надеюсь, это поможет.

0 голосов
/ 09 января 2019

Ваша ошибка в том, что вы не закрываете свой метод конструктора:

public ClientGUI() throws IOException {
    ssocket = new Socket();
// } should be closed her, but was not

 public int sendToServer(String text) {
     ...
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...