Hi !
First, congratulations for the 1.0.3 and 1.1 releases.
Second, a problem I encounter again... Unbinding on Linux.
My problem is that when I do a restart on my service, I can bind on the address (Address already in use). No problem on windows.

A question : Is SocketAcceptor.unbindAll() synchronous ? I mean everything is unbind after the call ?

Second my testcase is attached. I change the Reverser example to show my problem The protocol handler is the same one : reverseProtocolHandler. And my main attached is Server.java. As you see I bind (localhost, 8080). Connect a client socket. UnbindAll. And try to rebind. Running it on linux lead to a java.net.SocketException: Address already in use.
Of course, if I don't connect a client, everything runs fine.

I know there was a bug (DIRMINA-366) and a long discussion about this subject. But the bug is closed in 1.0.3 and the discussion seems to be close. Maybe I miss something during the discussion... Could you please tell me what ?

Nicolas Froment



package org.apache.mina.example.reverser;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.util.Properties;

import org.apache.log4j.PropertyConfigurator;
import org.apache.mina.filter.LoggingFilter;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.SocketAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;


public class Server
{
        private static final int        PORT    = 8080;

        private SocketAcceptor          acceptor;
        private boolean                         bind;

        public static void main(String[] args) throws Exception
        {
                Server server = new Server();
                server.initLogging();
                server.go();
        }

        private void initLogging()
        {
                Properties props = new Properties();

                props.put("log4j.rootCategory", "INFO, app");
                props.put("log4j.appender.app", 
"org.apache.log4j.ConsoleAppender");
                props.put("log4j.appender.app.Threshold", "DEBUG");
                props.put("log4j.appender.app.layout", 
"org.apache.log4j.PatternLayout");
                props.put("log4j.appender.app.layout.ConversionPattern", " 
[%d{yyyy-MM-dd HH:mm:ss}]-[%5p]-[%t]-[%25.25C{1}] - %m%n");

                PropertyConfigurator.configure(props);

        }

        private void go()
        {
                // Add the JVM exit hook
                Shutdown shutdown = new Shutdown(this);
                Runtime.getRuntime().addShutdownHook(shutdown);

                acceptor = new SocketAcceptor();

                // Prepare the configuration
                SocketAcceptorConfig cfg = new SocketAcceptorConfig();
                cfg.setReuseAddress(true);
                cfg.getFilterChain().addLast("logger", new LoggingFilter());
                cfg.getFilterChain().addLast("codec", new 
ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));

                ((SocketAcceptorConfig) 
acceptor.getDefaultConfig()).setReuseAddress(true);

                // Bind
                try
                {
                        acceptor.bind(new InetSocketAddress("localhost", PORT), 
new ReverseProtocolHandler(), cfg);
                        bind = true;
                        System.out.println("Listening on port " + PORT);
                }
                catch (IOException e)
                {
                        // Auto-generated catch block
                        e.printStackTrace();
                }

                //Connect
                try
                {
                        InetAddress addr = InetAddress.getByName("localhost");

                        // This constructor will block until the connection 
succeeds
                        Socket socket = new Socket(addr, PORT);
                }
                catch (UnknownHostException e)
                {
                        e.printStackTrace();
                }
                catch (IOException e)
                {
                        e.printStackTrace();
                }
                
                System.out.println("Connected");
                
                
                //UNBIND !!
                acceptor.unbindAll();
                bind = false;
                System.out.println("Unbind : " + PORT);
                
                
                // ReBind
                try
                {
                        acceptor.bind(new InetSocketAddress("localhost", PORT), 
new ReverseProtocolHandler(), cfg);
                        bind = true;
                        System.out.println("Listening on port " + PORT);
                }
                catch (IOException e)
                {
                        // Auto-generated catch block
                        e.printStackTrace();
                }
                
        }

        public void stop()
        {
                acceptor.unbindAll();
                bind = false;
        }
}

Reply via email to