diff --git a/components/net/sf/briar/plugins/socket/SocketPlugin.java b/components/net/sf/briar/plugins/socket/SocketPlugin.java
index abf94d60c90e291de1cc6706b6f1c907917a2899..3a970a517ebbc2e028b6a78aee0c2d2089f21cbe 100644
--- a/components/net/sf/briar/plugins/socket/SocketPlugin.java
+++ b/components/net/sf/briar/plugins/socket/SocketPlugin.java
@@ -50,30 +50,74 @@ abstract class SocketPlugin implements StreamTransportPlugin {
 		executor.execute(createBinder());
 	}
 
-	protected Runnable createBinder() {
+	private Runnable createBinder() {
 		return new Runnable() {
 			public void run() {
-				SocketAddress addr;
-				ServerSocket s;
-				try {
-					synchronized(SocketPlugin.this) {
-						if(!started) return;
-						addr = getLocalSocketAddress();
-						s = createServerSocket();
+				bind();
+			}
+		};
+	}
+
+	private void bind() {
+		SocketAddress addr;
+		ServerSocket ss;
+		try {
+			synchronized(this) {
+				if(!started) return;
+				addr = getLocalSocketAddress();
+				ss = createServerSocket();
+			}
+			if(addr == null || ss == null) return;
+			ss.bind(addr);
+		} catch(IOException e) {
+			// FIXME: Logging
+			return;
+		}
+		synchronized(this) {
+			if(!started) return;
+			socket = ss;
+			setLocalSocketAddress(ss.getLocalSocketAddress());
+			startListener();
+		}
+	}
+
+	private void startListener() {
+		new Thread() {
+			@Override
+			public void run() {
+				listen();
+			}
+		}.start();
+	}
+
+	private void listen() {
+		while(true) {
+			ServerSocket ss;
+			Socket s;
+			synchronized(this) {
+				if(!started) return;
+				ss = socket;
+			}
+			try {
+				s = ss.accept();
+			} catch(IOException e) {
+				// FIXME: Logging
+				return;
+			}
+			synchronized(this) {
+				if(!started) {
+					try {
+						s.close();
+					} catch(IOException e) {
+						// FIXME: Logging
 					}
-					if(addr == null || s == null) return;
-					s.bind(addr);
-				} catch(IOException e) {
-					// FIXME: Logging
 					return;
 				}
-				synchronized(SocketPlugin.this) {
-					if(!started) return;
-					socket = s;
-					setLocalSocketAddress(s.getLocalSocketAddress());
-				}
+				SocketTransportConnection conn =
+					new SocketTransportConnection(s);
+				callback.incomingConnectionCreated(conn);
 			}
-		};
+		}
 	}
 
 	public synchronized void stop() throws IOException {
@@ -109,20 +153,25 @@ abstract class SocketPlugin implements StreamTransportPlugin {
 		}
 	}
 
-	protected Runnable createConnector(final ContactId c) {
+	private Runnable createConnector(final ContactId c) {
 		return new Runnable() {
 			public void run() {
-				StreamTransportConnection conn = createAndConnectSocket(c);
-				if(conn != null) {
-					synchronized(SocketPlugin.this) {
-						if(started) callback.outgoingConnectionCreated(c, conn);
-					}
-				}
+				connect(c);
 			}
 		};
 	}
 
-	protected StreamTransportConnection createAndConnectSocket(ContactId c) {
+	private StreamTransportConnection connect(ContactId c) {
+		StreamTransportConnection conn = createAndConnectSocket(c);
+		if(conn != null) {
+			synchronized(this) {
+				if(started) callback.outgoingConnectionCreated(c, conn);
+			}
+		}
+		return conn;
+	}
+
+	private StreamTransportConnection createAndConnectSocket(ContactId c) {
 		SocketAddress addr;
 		Socket s;
 		try {
diff --git a/test/net/sf/briar/plugins/socket/SimpleSocketPluginTest.java b/test/net/sf/briar/plugins/socket/SimpleSocketPluginTest.java
index aaa0e3b8e80afe31c312940c75dc59c82c1d9e8e..33182d0d3dbc96f894a32cbd956dcb4f99cb5434 100644
--- a/test/net/sf/briar/plugins/socket/SimpleSocketPluginTest.java
+++ b/test/net/sf/briar/plugins/socket/SimpleSocketPluginTest.java
@@ -1,5 +1,8 @@
 package net.sf.briar.plugins.socket;
 
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.TreeMap;
@@ -30,21 +33,34 @@ public class SimpleSocketPluginTest extends TestCase {
 	}
 
 	@Test
-	public void testBind() throws Exception {
+	public void testBindAndAccept() throws Exception {
 		StubCallback callback = new StubCallback();
 		localProperties.put("host", "127.0.0.1");
 		localProperties.put("port", "0");
 		SimpleSocketPlugin plugin =
 			new SimpleSocketPlugin(new ImmediateExecutor(), 10);
 		plugin.start(localProperties, remoteProperties, config, callback);
+		// The plugin should have bound a socket and stored the port number
 		assertNotNull(callback.localProperties);
 		String host = callback.localProperties.get("host");
 		assertNotNull(host);
 		assertEquals("127.0.0.1", host);
-		String port = callback.localProperties.get("port");
-		assertNotNull(port);
-		assertTrue(Integer.valueOf(port) > 0 && Integer.valueOf(port) < 65536);
+		String portString = callback.localProperties.get("port");
+		assertNotNull(portString);
+		int port = Integer.valueOf(portString);
+		assertTrue(port > 0 && port < 65536);
+		// The plugin should be listening on the port
+		InetSocketAddress addr = new InetSocketAddress(host, port);
+		Socket s = new Socket();
+		s.connect(addr, 100);
+		s.close();
+		// Stop the plugin
 		plugin.stop();
+		// The plugin should no longer be listening
+		try {
+			s.connect(addr, 100);
+			fail();
+		} catch(IOException expected) {}
 	}
 
 	private static class ImmediateExecutor implements Executor {