Accept connections on the local socket.

This commit is contained in:
akwizgran
2011-10-06 12:00:44 +01:00
parent 1ee765a052
commit 5bc9baff95
2 changed files with 97 additions and 32 deletions

View File

@@ -50,32 +50,76 @@ 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();
}
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());
}
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
}
return;
}
SocketTransportConnection conn =
new SocketTransportConnection(s);
callback.incomingConnectionCreated(conn);
}
}
}
public synchronized void stop() throws IOException {
if(!started) throw new IllegalStateException();
started = false;
@@ -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 {

View File

@@ -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 {