2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-08-22 18:07:55 +00:00

Dynamic tcp port change when bind fails

This commit is contained in:
Albert Vaca 2013-08-08 04:12:28 +02:00
parent ec7333dc9a
commit 27f7e54c7f
3 changed files with 126 additions and 96 deletions

View File

@ -238,6 +238,7 @@ public class BackgroundService extends Service {
@Override @Override
public void onDestroy() { public void onDestroy() {
Log.i("BackgroundService", "Destroying"); Log.i("BackgroundService", "Destroying");
stopDiscovery();
super.onDestroy(); super.onDestroy();
} }

View File

@ -25,6 +25,11 @@ public class NioSessionComputerLink extends BaseComputerLink {
private IoSession session = null; private IoSession session = null;
public void disconnect() {
Log.e("NioSessionComputerLink","Disconnect: "+session.getRemoteAddress().toString());
session.close(true);
}
public NioSessionComputerLink(IoSession session, String deviceId, BaseLinkProvider linkProvider) { public NioSessionComputerLink(IoSession session, String deviceId, BaseLinkProvider linkProvider) {
super(deviceId, linkProvider); super(deviceId, linkProvider);
this.session = session; this.session = session;

View File

@ -64,6 +64,10 @@ public class BroadcastTcpLinkProvider extends BaseLinkProvider {
NioSessionComputerLink prevLink = nioSessions.get(session.getId()); NioSessionComputerLink prevLink = nioSessions.get(session.getId());
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) { if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
String myId = NetworkPackage.createIdentityPackage(context).getString("deviceId");
if (np.getString("deviceId").equals(myId)) {
return;
}
NioSessionComputerLink link = new NioSessionComputerLink(session, np.getString("deviceId"), BroadcastTcpLinkProvider.this); NioSessionComputerLink link = new NioSessionComputerLink(session, np.getString("deviceId"), BroadcastTcpLinkProvider.this);
nioSessions.put(session.getId(),link); nioSessions.put(session.getId(),link);
addLink(np, link); addLink(np, link);
@ -78,50 +82,7 @@ public class BroadcastTcpLinkProvider extends BaseLinkProvider {
} }
}; };
private void addLink(NetworkPackage identityPackage, NioSessionComputerLink link) { private IoHandler udpHandler = new IoHandlerAdapter() {
Log.e("BroadcastTcpLinkProvider","addLink to "+identityPackage.getString("deviceName"));
String deviceId = identityPackage.getString("deviceId");
BaseComputerLink oldLink = visibleComputers.get(deviceId);
if (oldLink != null) {
Log.e("BroadcastTcpLinkProvider","Removing old connection to same device");
connectionLost(oldLink);
}
visibleComputers.put(deviceId, link);
connectionAccepted(identityPackage, link);
}
public BroadcastTcpLinkProvider(Context context) {
this.context = context;
//This handles the case when I'm the new device in the network and somebody answers my introduction package
tcpAcceptor = new NioSocketAcceptor();
tcpAcceptor.setHandler(tcpHandler);
tcpAcceptor.getSessionConfig().setKeepAlive(true);
//TextLineCodecFactory will split incoming data delimited by the given string
tcpAcceptor.getFilterChain().addLast("codec",
new ProtocolCodecFilter(
new TextLineCodecFactory(Charset.defaultCharset(), LineDelimiter.UNIX, LineDelimiter.UNIX)
)
);
try {
tcpAcceptor.getSessionConfig().setReuseAddress(true);
tcpAcceptor.bind(new InetSocketAddress(port));
} catch(Exception e) {
Log.e("BroadcastTcpLinkProvider", "Error: Could not bind tcp socket");
e.printStackTrace();
}
}
@Override
public void onStart() {
//This handles the case when I'm the existing device in the network and receive a "hello" UDP package
udpAcceptor = new NioDatagramAcceptor();
udpAcceptor.getSessionConfig().setReuseAddress(true); //Share port if existing
udpAcceptor.setHandler(new IoHandlerAdapter() {
@Override @Override
public void messageReceived(IoSession udpSession, Object message) throws Exception { public void messageReceived(IoSession udpSession, Object message) throws Exception {
super.messageReceived(udpSession, message); super.messageReceived(udpSession, message);
@ -147,13 +108,14 @@ public class BroadcastTcpLinkProvider extends BaseLinkProvider {
return; return;
} else { } else {
String myId = NetworkPackage.createIdentityPackage(context).getString("deviceId"); String myId = NetworkPackage.createIdentityPackage(context).getString("deviceId");
if (np.getType().equals(myId)) { if (np.getString("deviceId").equals(myId)) {
return; return;
} }
} }
Log.e("BroadcastTcpLinkProvider", "It is an identity package, creating link"); Log.e("BroadcastTcpLinkProvider", "It is an identity package, creating link");
try {
final InetSocketAddress address = (InetSocketAddress) udpSession.getRemoteAddress(); final InetSocketAddress address = (InetSocketAddress) udpSession.getRemoteAddress();
final NioSocketConnector connector = new NioSocketConnector(); final NioSocketConnector connector = new NioSocketConnector();
@ -166,7 +128,8 @@ public class BroadcastTcpLinkProvider extends BaseLinkProvider {
); );
connector.getSessionConfig().setKeepAlive(true); connector.getSessionConfig().setKeepAlive(true);
ConnectFuture future = connector.connect(new InetSocketAddress(address.getAddress(), port)); int tcpPort = np.getInt("tcpPort",port);
ConnectFuture future = connector.connect(new InetSocketAddress(address.getAddress(), tcpPort));
future.addListener(new IoFutureListener<IoFuture>() { future.addListener(new IoFutureListener<IoFuture>() {
@Override @Override
public void operationComplete(IoFuture ioFuture) { public void operationComplete(IoFuture ioFuture) {
@ -184,16 +147,63 @@ public class BroadcastTcpLinkProvider extends BaseLinkProvider {
} }
}); });
} } catch (Exception e) {
Log.e("BroadcastTcpLinkProvider","Exception!!");
e.printStackTrace();
} }
}); }
}
};
private void addLink(NetworkPackage identityPackage, NioSessionComputerLink link) {
Log.e("BroadcastTcpLinkProvider","addLink to "+identityPackage.getString("deviceName"));
String deviceId = identityPackage.getString("deviceId");
BaseComputerLink oldLink = visibleComputers.get(deviceId);
if (oldLink != null) {
Log.e("BroadcastTcpLinkProvider","Removing old connection to same device");
connectionLost(oldLink);
}
visibleComputers.put(deviceId, link);
connectionAccepted(identityPackage, link);
}
public BroadcastTcpLinkProvider(Context context) {
this.context = context;
//This handles the case when I'm the new device in the network and somebody answers my introduction package
tcpAcceptor = new NioSocketAcceptor();
tcpAcceptor.setHandler(tcpHandler);
tcpAcceptor.getSessionConfig().setKeepAlive(true);
tcpAcceptor.getSessionConfig().setReuseAddress(true);
tcpAcceptor.setCloseOnDeactivation(false);
//TextLineCodecFactory will split incoming data delimited by the given string
tcpAcceptor.getFilterChain().addLast("codec",
new ProtocolCodecFilter(
new TextLineCodecFactory(Charset.defaultCharset(), LineDelimiter.UNIX, LineDelimiter.UNIX)
)
);
udpAcceptor = new NioDatagramAcceptor();
udpAcceptor.getSessionConfig().setReuseAddress(true); //Share port if existing
//TextLineCodecFactory will split incoming data delimited by the given string //TextLineCodecFactory will split incoming data delimited by the given string
udpAcceptor.getFilterChain().addLast("codec", udpAcceptor.getFilterChain().addLast("codec",
new ProtocolCodecFilter( new ProtocolCodecFilter(
new TextLineCodecFactory(Charset.defaultCharset(), LineDelimiter.UNIX, LineDelimiter.UNIX) new TextLineCodecFactory(Charset.defaultCharset(), LineDelimiter.UNIX, LineDelimiter.UNIX)
) )
); );
}
@Override
public void onStart() {
//This handles the case when I'm the existing device in the network and receive a "hello" UDP package
udpAcceptor.setHandler(udpHandler);
try { try {
udpAcceptor.bind(new InetSocketAddress(port)); udpAcceptor.bind(new InetSocketAddress(port));
} catch(Exception e) { } catch(Exception e) {
@ -201,25 +211,29 @@ public class BroadcastTcpLinkProvider extends BaseLinkProvider {
e.printStackTrace(); e.printStackTrace();
} }
onNetworkChange(); boolean success = false;
int tcpPort = port;
while(!success) {
try {
tcpAcceptor.bind(new InetSocketAddress(tcpPort));
success = true;
} catch(Exception e) {
tcpPort++;
}
} }
@Override Log.e("BroadcastTcpLinkProvider","Using tcpPort "+tcpPort);
public void onNetworkChange() {
Log.e("BroadcastTcpLinkProvider","OnNetworkChange: " + (udpAcceptor != null));
if (udpAcceptor == null) return;
//I'm on a new network, let's be polite and introduce myself //I'm on a new network, let's be polite and introduce myself
final int finalTcpPort = tcpPort;
new AsyncTask<Void,Void,Void>() { new AsyncTask<Void,Void,Void>() {
@Override @Override
protected Void doInBackground(Void... voids) { protected Void doInBackground(Void... voids) {
try { try {
String s = NetworkPackage.createIdentityPackage(context).serialize(); NetworkPackage identity = NetworkPackage.createIdentityPackage(context);
byte[] b = s.getBytes("UTF-8"); identity.set("tcpPort",finalTcpPort);
byte[] b = identity.serialize().getBytes("UTF-8");
DatagramPacket packet = new DatagramPacket(b, b.length, InetAddress.getByAddress(new byte[]{-1,-1,-1,-1}), port); DatagramPacket packet = new DatagramPacket(b, b.length, InetAddress.getByAddress(new byte[]{-1,-1,-1,-1}), port);
DatagramSocket socket = new DatagramSocket(); DatagramSocket socket = new DatagramSocket();
socket.setReuseAddress(true); socket.setReuseAddress(true);
@ -232,18 +246,28 @@ public class BroadcastTcpLinkProvider extends BaseLinkProvider {
} }
return null; return null;
} }
}.execute(); }.execute();
}
@Override
public void onNetworkChange() {
Log.e("BroadcastTcpLinkProvider","OnNetworkChange: " + (udpAcceptor != null));
onStop();
onStart();
} }
@Override @Override
public void onStop() { public void onStop() {
if (udpAcceptor != null) {
udpAcceptor.unbind(); udpAcceptor.unbind();
udpAcceptor = null; tcpAcceptor.unbind();
}
} }