Sockets left in CLOSE_WAIT on server
engluer Oct 4, 2007 2:08 PMI was trying to cleaning close a connection to a JBoss server. I have tried the following on both JBoss 4.2.2 with Messaging and JBoss 5 b2 and in both cases when the client closes the connection a socket is left in the CLOSE_WAIT state on the server. In both cases I was using the BiSocket transport
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.naming.InitialContext;
import javax.naming.NamingException;
/*
*
* Note monitor server connections with
* watch "/usr/sbin/lsof -p [pid of Jboss server] | grep -c CLOSE_WAIT"
*
*/
public class SimpleSubscriber implements MessageListener {
private Session subSession;
private Connection connection;
private String destName;
private String password;
private String username;
private ConnectionFactory conFactory;
private InitialContext ic;
private MessageConsumer subscriber;
public SimpleSubscriber(String destName, String username, String password) {
this.destName = destName;
this.username = username;
this.password = password;
}
private void connect() throws NamingException, JMSException {
if (ic == null) {
ic = new InitialContext();
}
//Look up JMS connection Factory
conFactory = (ConnectionFactory)ic.lookup("/ConnectionFactory");
//Lookup Destination
Object obj = ic.lookup(destName);
Destination topic = (Destination)obj;
//Create JMS connection
connection = conFactory.createConnection(username, password);
//Create two JMS session objects
subSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
subscriber = subSession.createConsumer(topic);
subscriber.setMessageListener(this);
//Start the connection
connection.start();
}
public void close() throws JMSException {
subscriber.close();
subSession.close();
connection.close();
}
public static void main(String [] args) {
String username = null;
String password = null;
String dest= null;
if (args.length != 3) {
printUsage();
return;
}
dest= args[0];
username = args[1];
password = args[2];
final SimpleSubscriber subscriber = new SimpleSubscriber(dest, username, password);
System.out.println("Connecting to JBoss...");
try {
subscriber.connect();
} catch (NamingException e) {
e.printStackTrace();
return;
} catch (JMSException e) {
e.printStackTrace();
return;
}
System.out.println("Connected");
System.out.println("Sleeping");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {}
System.out.println("Disconnecting");
try {
subscriber.close();
} catch (JMSException e) {
e.printStackTrace();
}
System.out.println("Closed");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {}
System.out.println("Done");
}
private static void printUsage() {
System.out.println("Subscriber <topic> [username] [password]"
+ "\ntopic: Name of topic to connect to pings with"
+ "\nusername: Username to connect with"
+ "\npassword: Password to connect with");
}
public void onMessage(Message arg0) {
System.out.println("Received Message: " + arg0);
}
}
Th above example connects waits, then disconnects and waits, then shuts down. Am I not closing the connection correctly? I am using the following to check for socket state.
watch "/usr/sbin/lsof -p [pid of Jboss server] | grep -c CLOSE_WAIT"
The server we are using has client connecting and disconnecting quite rapidly and we quickly run out of file descriptors because of all the CLOSE_WAIT sockets left open.