Skip to Main Content

Java APIs

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Stopping a server Thread that creates connection Threads for Socket I/O

843790Oct 1 2007 — edited Oct 2 2007
Hi,

I'm new to this forum, so please don't scream at me if I posted this in the wrong place or something. I'm having trouble with this simple daemon that I'm writing. It's your basic socket I/O application: a Daemon thread loops, waiting for client connections. When a client connection request is made, the Daemon creates a new Connection thread to handle it and goes back to listen for more connections. This part works fine, but the problem occurs when I try to stop the Daemon thread and then start it again.

Here's the scenario: If I start the daemon to listen to port 12345 and then stop the daemon and then start the daemon again on port 12345, I get the following error because the Socket(s) from the first time I ran the daemon still haven't been disconnected.

java.net.BindException: Address already in use: JVM_Bind
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at server.Daemon.run(Daemon.java:18)
at java.lang.Thread.run(Unknown Source)

Here is the portion of the code that is causing the problem:
// This is basically a GUI window that has buttons to start and stop the server

public class ConfigWindow extends JDialog implements ActionListener {
    private Daemon daemon;
    private Thread thread = null;
...
    public void actionPerformed(ActionEvent ae) {
        if ("start".equals(ae.getActionCommand())) {
            daemon = new Daemon(12345);
            thread = new Thread(daemon);
            thread.setDaemon(true);
            thread.start();
        } else if ("stop".equals(ae.getActionCommand())) {
            daemon.stop();
            thread = null;
        }
    } // actionPerformed
...
} // ConfigWindow
import java.io.*;
import java.net.*;

public class Daemon implements Runnable {
    private int port = 0;
    private boolean isAlive;

    public Daemon() {
    } // default constructor

    public Daemon(int port) {
        this.port = port;
    } // optional constructor

    public void run() {
        try {
            ServerSocket socket = new ServerSocket(port);
            isAlive = true;
            while (isAlive) {
                Thread thread = new Thread(new Connection(socket.accept()));
                thread.setDaemon(true);
                thread.start();
            }
            socket.close();
        } catch (IOException ioe) {
            System.err.println(ioe);
            System.exit(-1);
        }
    } // run

    public void setPort(int port) {
        this.port = port;
    } // setPort

    public void stop() {
        isAlive = false;
    } // stop
} // Daemon
import java.io.*;
import java.net.*;

public class Connection implements Runnable {
    private Socket socket;

    public Connection(Socket socket) {
        this.socket = socket;
    } // constructor

    public void run() {
        try {
// will do something here eventually
            socket.close();
        } catch (IOException ioe) {
        }
    } // run
} // Connection
If, in the while loop of Daemon's run(), I don't connect to anything, the daemon will shut down and restart on the same port # without any problems. However, when I run the code as it is above, the port # is held open, and if ConfigWindow.actionPerformed() is called again from clicking the start button (not shown above), the program will end with a "java.net.BindException: Address already in use: JVM_Bind" because a lost thread is still waiting for a connection on port 12345 from the first time the daemon was started.

Oh, and did I mention that this problem occurs even if the daemon NEVER receives a client connection request!?!

I don't think this should be that complicated. Someone with thread and socket I/O experience should be able to spot the problem right away.

Thanks!

Edited by: CaptainOatz on Oct 1, 2007 2:38 AM
I'm also trying to figure out how to use code tags =/ ...
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Oct 30 2007
Added on Oct 1 2007
7 comments
763 views