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.