DNB5brims
DNB5brims

Reputation: 30568

Why it warns me the socket is closed when I quit the programme?

Here is my programme, which have a two threads, one is listening user input, another is a socket:

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

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

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

The worker is a socket, and the BasicConsoleIO is responsible for listening the user input The BasicConsoleIO is something like that:

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);
}

When it press 'q', the application will call the worker to close the socket, and quit the program, and the Worker works this way:

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();
    }
}

The worker will keep listening the request, and assign the new work task in a separate thread, the details of worktask like this:

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();
    }
}

But When I launch the programme, and press 'q' to exit, it warns me with this error:

Please assign a port number 2333 Press 'q' to kill to programme Waiting for connection: 2333 q worker stop working Run me anyway! java.net.SocketException: Socket closed at java.net.PlainSocketImpl.socketAccept(Native Method) at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408) at java.net.ServerSocket.implAccept(ServerSocket.java:462) at java.net.ServerSocket.accept(ServerSocket.java:430) at com.mydefault.package.Worker.run(Worker.java:61) at java.lang.Thread.run(Thread.java:680)

Upvotes: 0

Views: 422

Answers (1)

Peter Lawrey
Peter Lawrey

Reputation: 533482

You can see the

socket = providerSocket.accept();

is throwing an exception because in

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();

you closed it.

If you want to avoid this error, I have a volatile boolean closed field which I set to true and check before I report an error. i.e. ignore errors when I am closing down.

Upvotes: 3

Related Questions