package net.i2p.router.client; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import net.i2p.client.DomainSocketFactory; import net.i2p.router.RouterContext; import net.i2p.util.Log; /** * Unix domain socket version of ClientListenerRunner. * * @author str4d * @since 0.9.14 */ public class DomainClientListenerRunner extends ClientListenerRunner { private final DomainSocketFactory factory; private final Log _log; public DomainClientListenerRunner(RouterContext context, ClientManager manager) { super(context, manager, -1); factory = new DomainSocketFactory(_context); _log = context.logManager().getLog(getClass()); } /** * @throws IOException */ @Override protected ServerSocket getServerSocket() throws IOException { return factory.createServerSocket(DomainSocketFactory.I2CP_SOCKET_ADDRESS); } @Override public void stopListening() { _running = false; // LocalServerSocket.close() fails silently if the socket is blocking in accept(), so we // trick the socket by opening a new connection and then immediately closing it. // http://stackoverflow.com/questions/8007982/java-serversocket-and-android-localserversocket try { _log.debug("Connecting to domain socket to trigger close"); Socket s = factory.createSocket(DomainSocketFactory.I2CP_SOCKET_ADDRESS); s.close(); } catch (IOException e) { _log.error("Failed to connect to domain socket to trigger close", e); } // runServer() will close the LocalServerSocket. } }