I've written a small file transfer program for android using standard Java sockets. The program works fine except for the following case:
I connect two android devices A and B over WiFi tethering connection. Device A is sharing the connection (enabled as wireless hotspot). When I run java server on A and client on B, the program works okay but when I run the server on device B, it can't accept any socket binding request from A. It doesn't throw any exception. Seems like the request is not reaching the server! However, both the devices are connected (ping test is okay in both directions). Can't I run socket server on a device connected as hotspot client? I thought once the networking is setup correctly, the application would work in any direction.
Also, Wireshark traces reveal nothing. What am I missing here? Please help! Here are my code snippets:
Server side (waiting for client connection):
while (true) {
try {
socket = serversocket.accept();
Runnable connectionHandler = new ConnectionHandler(
socket, fileArray, filepathNameArray,
SenderActivity.this, userID, handler);
new Thread(connectionHandler).start();
userID = userID + 1;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I would appreciate any kind of help! Thanks in advance.
Related
We are developing some internal apps for mobile devices that are connected to internal wifis. We have some problems because we are only checking if the devices are connected using ConnectivityManager. But we need to check not only if there is connection, we need to check that the connection between the device and the server is working.
The problem is that ConnectivityManager tell us that the wifi is connected. But if the device is in an area with little coverage the app have errors trying to connect.
How can we easily check that the connection we have open against the server is still responding correctly? For example, one of the applications the connection is open against a SQL Server. Is there any way to check that we get to the server and it gives us an ok, and that we are not losing the connection and the packages because of the low coverage?
Thanks!!
You can try pinging the server if you receive a NullPointerException or IOException most likely there is no connection or connection timed out.
you can read more here an answer to similar question by syb0rg. Also remember to wrap this piece of code in an AsyncTask or a Thread to prevent your app from crashing.
try {
//replace URL with your domain
URL url = new URL("http://www.google.com");
HttpURLConnection urlConnect = (HttpURLConnection) url.openConnection();
urlConnect.setConnectTimeout(1000);
urlConnect.getContent();
System.out.println("Connection established.");
} catch (NullPointerException np) {
np.printStackTrace();
} catch (IOException io) {
io.printStackTrace();
}
To be clear, this question is referencing the Android SDK for SignalR...not SignalR running in a browser on an android device.
For some reason, I can not establish a connection to the server when using my wireless data network (3g). I'm able to connect to my server via web services and receive a JSON string of data, but SignalR will not connect.
SignalRFuture<Void> awaitConnection = connection.start();
try {
awaitConnection.get(5000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// Handle ...
} catch (ExecutionException e) {
// Handle ...
} catch (TimeoutException e) {
Log.d(TAGSR,"it timed out");
e.printStackTrace();
}
this hits the timeout exception always when I'm NOT on WiFi...even if I bump it up to a minute +. What's weird is that as soon as it times out, the other aforementioned data loads instantly. If I turn my WiFi on my phone, this connects no problem at all.
Using the same SignalR connection with my browser, I'm able to connect via 3g with no problems at all...it's only the Android SDK version that pukes unless it's on WiFi. Is there some built in mechanism to the SDK that requires a certain connection speed? If so, is there a way to override that value? My 3g ain't a ferrari, but it's fast enough to work over the web version, and work fine at that....
any ideas?
TIA
no idea why, but it appears that it's the transport selection that's causing a failure on 3g.
when I comment out one or the other (serversentevents or longpolling) in AutomaticTransport, it works fine...
private void initialize(Logger logger) {
mTransports = new ArrayList<ClientTransport>();
mTransports.add(new ServerSentEventsTransport(logger));
//mTransports.add(new LongPollingTransport(logger));
}
I'm using this to upload some file. It works if I in a local connection, but if I use a external connection, i get this message: 425 Can't open data connection. from the ftp server.
I use the org.apache.commons.net.ftp.FTPClient and org.apache.commons.net.ftp.FTPFile libs.
public static String gravaImagem(String photoFile) {
FTPClient mFtp = new FTPClient();
try {
mFtp.connect(FTPHOST, PORTA);
mFtp.login(USUARIO, SENHA);
mFtp.setFileTransferMode(FTPClient.BINARY_FILE_TYPE);
mFtp.setFileType(FTPClient.BINARY_FILE_TYPE);
String origem = Environment.getExternalStorageDirectory().getPath()+File.separator+"Pictures"+File.separator+"ImageSec"+File.separator+photoFile;
FileInputStream fis = new FileInputStream(origem);
mFtp.storeFile(photoFile, fis);
mFtp.logout();
mFtp.disconnect();
} catch (SocketException e) {
e.printStackTrace();
return "Fail. (ERR#CON3)";
} catch (IOException e) {
e.printStackTrace();
return "Fail. (ERR#CON4)";
}
return "Imagem enviada ao servidor.";
}
Debug shows no exceptions.
From the internet:
First - the most common solution: change the active/passive mode
settings. But that might not work, and if it does its only a band-aid
covering up the real problem.
As I've mentioned in the past, one of the most common reasons that
this error occurs is a misconfiguration of the FTP server software
itself, related to SSL connections and firewalls, in which the
connection tries to establish itself on a bogus ip address. Read more
about FTP SSL through a NAT firewall here, some potential solutions
are included.
There are other less likely causes, such as:
The server is configured to always use the same port for passive mode connections, or the client is configured to always use the
same port for active mode connections, although in this case
usually the software in question should raise a different error
first, but I've seen this happen.
In passive mode, the firewall in front of the FTP server doesn't have the correct ports open. So the server tells the client to
connect to ipaddress 1.2.3.4 on port x, but the firewall doesn't
allow incoming connections on port x. Most firewalls are smart
enough to open up the port when it sees the PASV response. Vice
versa for active mode and the firewall in front of the FTP client.
From me:
I've used this library on andoird and it worked well, so see my copy/paste section.
I am creating one SerevrSocket with some port number.
But sometimes I get BindException saying Address already in use.
So is there any mechanism by which I can check before binding ServerSocket whether it is in use or not.
And also what is the best way of handling BindException?
sounds like you aren't closing your socket correctly before your program exits.
The socket needs to be closed in onDestroy method.
try {
ServerSocket server = new ServerSocket(0);
port = server.getLocalPort();
server.close();
}
catch (Exception e1){
Log.e("Error in Finding socket",e1.getMessage());
}
above code snippet gives you the free port available. But as mentioned earlier, check the socket closure for previous connections.
I've worked before with Kryonet doing 1-to-1 communication and it worked nicely.
Now I'm doing a more 'standard' project where we'll have 1 server and several clients to connect to it.
The issue I'm having is as described in the title: client 1 connects, no problem. Then I ask for client 2 to connect and immediately client 1 disconnects. Somehow the server doesn't want to keep more than one simultaneous connection.
A couple of times we managed to have 2 connected and then whenever the 3rd connects the other drops.
Running on several different devices all ICS+ (galaxy nexus, tab2, SGS3).
The codes I'm using are very much like the examples:
server side:
server = new Server();
ServiceData.RegisterKryo(server.getKryo());
server.addListener(new MyServerListener());
try {
server.bind(ServiceData.SERVER_PORT_TCP);
server.start();
} catch (IOException e) {
Log.e(TAG, "IOException. Failed to start server. " + e.getMessage());
MyServer.this.stopSelf();
}
And then client side:
final String ip = intent.getExtras().getString(KEY_SERVER_IP);
listener = new MyClientListener();
client = new Client();
client.start();
ServiceData.RegisterKryo(client.getKryo());
client.addListener(listener);
try {
client.connect(5000, ip, ServiceData.SERVER_PORT_TCP);
} catch (IOException e) {
Log.e(TAG, "IOException. Failed to start client. " + e.getMessage() + "\n");
e.printStackTrace();
MyClient.this.stopSelf();
}
the listeners at the moment are just Log.v(TAG, "something happened); and I've also enabled all the logs from the Kryonet library with com.esotericsoftware.minlog.Log.set(com.esotericsoftware.minlog.Log.LEVEL_TRACE); so I can see when it's connecting and when it's disconnecting.
I receive two different messages upon disconnection:
DEBUG: [kryonet] Connection 3 timed out.
and
DEBUG: [kryonet] Unable to read TCP from:
really not sure what's on here and any help will be appreciated.
edit:
a bit more info:
I've realised that between INFO: [kryonet] Connection 3 connected: /192.168.0.104 and my listener receive the connected callback, it's taking around 9 seconds! Very odd.
To whom might get into the same issue.
Apparently it's an Android limitation (probably imposed because it's a mobile device)
I just moved the Server code to a normal Java application .jar and let the Android clients connect to the PC and it all works fine now. Until now tested with 6 devices connected with no problems.