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 =/ ...