JAVA: получение экземпляра объекта из класса - PullRequest
0 голосов
/ 15 октября 2019

У меня проблема с возвратом экземпляра объекта, который определен внутри класса, в приведенном ниже коде я попытался установить Socket соединение внутри класса, которое расширяет Thread. socket_connect класс:

public class socket_connect extends Thread {
    private Socket socket;
    private OutputStream out;
    private String host;
    private int port;
    socket_connect(String host,int port){
        this.host=host;
        this.port=port;
        this.start();
    }
    @Override
    public void run() {
        try {
            this.socket = new Socket(this.host,this.port);
            this.out=new BufferedOutputStream(this.socket.getOutputStream());
            this.out.write("i am here \n\r".getBytes());
            this.out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public int getPort() {
        return port;
    }
    public String getHost() {
        return host;
    }
    public Socket getSocket() {
              return socket;
    }
    public  OutputStream getOut() {
        return out;
    }
}

основной класс:

public class mymain {
public static void main(String[] args) {
    Socket backsock;
    String backhost;
    int backport;
    String msg ="Second Hi!!!!!";
    socket_connect sc = new socket_connect("127.0.0.1",8080);
    backsock = sc.getSocket();
    backhost = sc.getHost();
    backport = sc.getPort();
    System.out.println(backhost + " " + backport);
    try {
        OutputStream buffer= new BufferedOutputStream(backsock.getOutputStream());
        buffer.write(msg.getBytes());
        buffer.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
    while (true) { }
}

}

Соединение установлено и Outputstream внутри класса Socket_connect будетнапиши "я здесь !!!"на сервер. но когда я пытаюсь выполнить другой процесс записи с New Outputstream, определенным внутри main, я получаю ошибку в строке OutputStream buffer= new BufferedOutputStream(backsock.getOutputStream());, кажется, что задний сокет, который я определил внутри основного файла, равен нулю. хотя я использовал backsock = sc.getSocket();, чтобы сделать тот же сокет, который я определил внутри экземпляра sc. однако gethost() и getPort() работают отлично:

backhost = sc.getHost();
backport = sc.getPort();
System.out.println(backhost + " " + backport);

это напечатает 127.0.0.1 8080 Я могу получить их обратно и сохранить их внутри int и строки, определенных в main, и использовать System.out для их печатино я не могу вернуть Socket или выходной поток из класса. они возвращаются null. Раньше я использовал C ++, и указатель указывал на точный объект в программе, но здесь я не могу.

Ответы [ 2 ]

1 голос
/ 15 октября 2019

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

public class socket_connect extends Thread {
    private Socket socket;
    private OutputStream out;
    private String host;
    private int port;
    private Semaphore sema = new Semaphore(1);

    socket_connect(String host, int port) {
        try {
            this.host = host;
            this.port = port;
            this.sema.acquire();
            this.start();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        try {
            this.socket = new Socket(this.host, this.port);
            this.out = new BufferedOutputStream(this.socket.getOutputStream());
            this.out.write("i am here \n\r".getBytes());
            this.out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            sema.release();
        }
    }

    public int getPort() throws InterruptedException {
            return port;
    }

    public String getHost() {
        return host;
    }

    public Socket getSocket() throws InterruptedException {
        try {
            sema.acquire();
            return socket;
        } finally {
            sema.release();
        }
    }

    public OutputStream getOut() throws InterruptedException {
        try {
            sema.acquire();
            return out;
        }finally {
            sema.release();
        }
    }

public static void main(String[] args) throws InterruptedException {
            Socket backsock;
            String backhost;
            int backport;
            String msg = "Second Hi!!!!!";
            socket_connect sc = new socket_connect("google.com", 80);
            backsock = sc.getSocket();
            backhost = sc.getHost();
            backport = sc.getPort();
            System.out.println(backhost + " " + backport);
            try {
                OutputStream buffer = new BufferedOutputStream(backsock.getOutputStream());
                buffer.write(msg.getBytes());
                buffer.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
}
1 голос
/ 15 октября 2019

Попробуйте запустить эту программу несколько раз, в некоторых случаях вы можете обнаружить, что она работает. Кажется, это проблема, связанная с темой. Когда вы выполняете, метод main может продолжить выполнение даже до того, как поток socket_connect начнет выполнять метод run(). Метод get host и port работает, потому что значения уже назначены вне метода run(). Вы можете просто проверить это, подождав несколько минут в основном методе, используя Thread.sleep(). Пример:

...
int backport;
String msg ="Second Hi!!!!!";
socket_connect sc = new socket_connect("127.0.0.1",8080);
// add try catch or throw 
// by this time hopefully the socket_connect will start.
Thread.sleep(1000);
backsock = sc.getSocket();
backhost = sc.getHost();
backport = sc.getPort();
System.out.println(backhost + " " + backport);

Примечание : также ожидание бесконечно while(true) - не очень хорошая практика. Все, что вы можете сделать, это попробовать что-то прочитать из входного потока сокетов.

...