Почему он предупреждает меня, что сокет закрывается при выходе из программы? - PullRequest
0 голосов
/ 13 марта 2012

Вот моя программа, в которой есть два потока, один из которых прослушивает ввод пользователя, другой - сокет:

        bio = new BasicConsoleIO();
        bio.assignObject(worker);

        Thread b = new Thread(bio);
        b.start();

        Thread a = new Thread(worker);
        a.start();

Рабочий - это сокет, а BasicConsoleIO отвечает за прослушивание ввода пользователя.BasicConsoleIO выглядит примерно так:

private Worker worker;
static BufferedReader reader;

@Override
public void run() {
    //......Code Skip......//
    if (inputString.equalsIgnoreCase("q")) {
        this.applicationQuit();
    }
}

public void applicationQuit(){
    this.getWorker().stopWorking();
    System.exit(0);
}

Когда он нажимает 'q', приложение вызывает рабочего, чтобы закрыть сокет, и выходит из программы, и Worker работает следующим образом:

private ServerSocket providerSocket;
private Socket socket = null;

int port = 1234;

Worker() {
}

public void stopWorking() {
    System.out.println("worker stop working");

    try {
        if (providerSocket != null) {
            providerSocket.close();
        }
        if (socket != null) {
            socket.close();
        }

    } catch (IOException ioException) {
        ioException.printStackTrace();
    }
}

@Override
public void run() {

    try {
        providerSocket = new ServerSocket(this.port);

        while (true) {
            if (!providerSocket.isClosed()) {

                socket = providerSocket.accept();

                WorkTask wt = new WorkTask();
                wt.setSocket(socket);

                Thread a = new Thread(wt);
                a.start();
            }
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
}

Рабочий продолжит прослушивать запрос и назначит новую рабочую задачу в отдельном потоке, детали рабочей задачи выглядят так:

Socket socket;
ObjectOutputStream out;
ObjectInputStream in;
Object receivedObj;
String message;

@Override
public void run() {
    try {

        do {
            out.flush();
            receivedObj = in.readObject();

                              //......Code Skip......//

        } while (receivedObj != null
                && !receivedObj.equals(SharedConstant.SOCKET_EOF_STRING));

        if (in != null) {
            in.close();
        }
        if (out != null) {
            out.close();
        }

    } catch (IOException e1) {
        e1.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

Но когда я запускаю программу и нажимаю 'q 'чтобы выйти, он предупреждает меня об этой ошибке:

Пожалуйста, назначьте номер порта 2333 Нажмите' q ', чтобы завершить работу программы Ожидание соединения: 2333 q Рабочий перестанет работать Запустите меня в любом случае!java.net.SocketException: сокет закрыт в java.net.PlainSocketImpl.socketAccept (собственный метод) в java.net.PlainSocketImpl.accept (PlainSocketImpl.java:408) в java.net.ServerSocket.implAccept (ServerSocket.java:462)на java.net.ServerSocket.accept (ServerSocket.java:430) на com.mydefault.package.Worker.run (Worker.java:61) на java.lang.Thread.run (Thread.java:680)

1 Ответ

3 голосов
/ 13 марта 2012

Вы можете увидеть

socket = providerSocket.accept();

выдает исключение, потому что в

public void stopWorking() {
    // Socket won't close unless the user make it to close
    // 4: Closing connection
    System.out.println("worker stop working");

    try {
        if (providerSocket != null) {
            providerSocket.close();

Вы закрыли его.

Если вы хотите избежать этой ошибки, у меня есть поле volatile boolean closed, которое я установил на true и проверяю, прежде чем сообщать об ошибке. то есть игнорировать ошибки при закрытии.

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