TheInsider
Programmer
Hi,
I'm having trouble with the simple daemon that I'm writing. It's a pretty 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 restart it.
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 "java.net.BindException: Address already in use: JVM_Bind" because the Connection thread(s) from the first time I ran the daemon still haven't been disconnected.
Here is the portion of the code that is causing the problem:
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".
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
I'm having trouble with the simple daemon that I'm writing. It's a pretty 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 restart it.
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 "java.net.BindException: Address already in use: JVM_Bind" because the Connection thread(s) from the first time I ran the daemon still haven't been disconnected.
Here is the portion of the code that is causing the problem:
Code:
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
Code:
package server;
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
Code:
package server;
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".
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