In my android application I am querying a database. I am only able to query the database if the phone is connected to the internal network, i.e: by being connected to company WiFi, or by using VPN connection.
I would like to check this connection first - maybe by trying to 'ping' the server first? Is this possible?
Thanks.
Just try to connect to the network/database/ip and handle any exception thrown b/c the network is unreachable or b/c of a time out.
You can also try InetAddress which has an isReachable() method.
You could consider using android.net.ConectivityManager if you really want to check the network status.
ConectivityManager.requestRouteToHost() can be used to ensure a server is reachable (although doubts have been raised about its reliability - mentioned in CommonsWare answer here : how to mange wifi internet connectivity in android? )
Alternatively, if you just want to check WIFI is connected, try
ConectivityManager.getNetworkInfo(ConectivityManager.TYPE_WIFI).isConnected()
Couple of caveats :
1) I'm typing this in a browser not an IDE, so it might have syntax errors,
2) You'll have to make that code much more defensive for production, and
3) All connectivity tests in ConectivityManager can be unreliable if networks are currently becoming available or unavailable.
Hope this covers what you were asking.
Related
I'm currently making a Java application that detects when smartphones connect to our home network. I'm able to get the IP addresses of all of the "remembered" devices on the network, ping the devices currently active on the network like desktops and laptops, but when I try to ping smartphones (either from command line or from the Java application using the InetAddress's isReachable() method) the requests time out.
Is this a problem with a security setting on our router? Do the phones (iPhones) themselves have security that prevents this? Is there any other Java code I can use to detect when these smartphones are or aren't active on the network? I haven't been able to find a particularly helpful answer so far in previous questions.
Thank you for reviewing my question!
It might be a good idea to inspect your network with Wireshark, or with an other similar software to see what is going on behind the scenses on your neteork. If you use linux, you may want to try the unix command arp-scan, which does network discovery for you.
I'm developing a Java Swing based app which uses JDBC to connect to a MySQL database. As such, the software directly remotely access the database from whichever computer it happens to be running on. Additionally, the app uses prepared statements to query the database and the database is hosted on a shared CPanel hosting account (if that matters).
The snippet of code I use to connect to the database is as follows (fairly standard connect code I think and all strings in all caps contain the correct contents):
String url = "jdbc:mysql://URL:PORT/DB_NAME?connectTimeout=3000";
Connection conn = DriverManager.getConnection(url, USERNAME, PASSWORD);
I have only ever successfully used the app from one IP. Before I use the app from an IP, I have to manually whitelist the IP by adding it as an allowed remote MySQL access host. If I don't add the IP as an allowed access host, the server refuses my connection and I get the resultant error:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
Then if I whitelist an IP and try to connect from it, I don't get that error and the app connects to the database properly.
This system would be okay if the app were only going to be used from one IP, but it needs to work from any IP since I cannot predict who will download and use it. The only solution I see would be to do a global whitelist of all IPs in the allowed MySQL access hosts area. However, that seems like it has many drawbacks, such as being insecure as anyone who has the correct password could log in (and would thus be susceptible to brute force attacks). This seems to corroborate the hypothesis that that method is insecure. Thus, I would like to have a system of communicating between the app and database that is IP-independent (doesn't require whitelisting all the IPs).
Additionally (I don't know if this makes sense or matters), but I believe some of the areas I expect the app to be used in block certain protocols. Thus, (I think) I would like it if the selected method of communication only used HTTP or some other widely-used protocol.
I did some research into this problem and my efforts led me to 2-tier and n-tier models of database communication. Perhaps I could do something like make a PHP page which accepts a statement and a series of parameters (plus a password to gain entry), executes the statement, and then returns the result back as JSON. However, this seems like another less-than-ideal method as it seems like it would also have security problems.
I'm sure someone more experienced and knowledgeable than I has already come across this problem and developed a solution.
Therefore, my question: What is the preferred method of connecting to a MySQL database from a Java app in an IP-independent way?
I greatly appreciate and thank you for your time.
You're on the right track:
1) If you want any arbitrary client to connect directly to your database, and the clients can have any arbitrary IP address ... then you're probably going to have to effectly disable IP security be whitelisting all possible client IP addresses.
2) On the other hand, if you only allow local access to mySql (by far the most common scenario), then you can create a web app to interface between your clients and mySql.
SUGGESTION:
Consider creating a "REST" web service that your clients can talk to.
Here's a good tutorial that might help you get started:
REST with Java (JAX-RS) using Jersey - Tutorial
Q: Does your Swing app really need to emit "raw SQL"? Or can it make "high level" queries? REST is ideally suited for the latter.
PS:
Here's another, short example that might help suggest some design alternatives with REST, mySQL and Java for you:
http://www.9lessons.info/2012/09/restful-web-services-api-using-java-and.html
You are up against the policies -- primarily the security policies -- of your hosting provider. It's generally considered insecure to allow port 3306 (MySQL) connections from the whole internet. It certainly lays your MySQL server open to trivial denial-of-service attacks. (It just takes some knucklehead controlling a botnet to send in lots of port 3306 connection attempts. They don't even have to be successful connection attempts.) If you're sharing your MySQL server with other customers of your hosting provider, they have every incentive to restrict your remote access to their server.
Most folks who build database applications for deployment on the public internet do it by providing web services to hit the database with the specific operations required by the application. The application deployed at the end-user's machine then uses HTTP (or HTTPS for security) to access those web services. In turn the web services access the database. That's what multitier operations do. You're right that there are security problems, but you can mitigate them with careful development of your web service code.
You could use SSH tunneling to handle your database access. The SSH suite of remote-access applications allows port forwarding. To use this, you would establish (authenticated and encrypted) ssh connections between your end-users' machines and your database machine, that forward port 3306. Then your users could connect to localhost:3306, and that net traffic would be forwarded to your database server. It's pretty flexible and quite secure, if not completely simple to configure.
You might also investigate using SQL Relay. It's generally used for connection pooling and management within a data center network, but it might work for this purpose.
Be careful opening up your MySQL server to the world! If you do that you may want to require the use of TLS encrypted conections.
I am writing a platform game, and i thought it would be cool to add a multi-player mode for people who are playing on the same network. My question is how would i query through all the available computers open on a certain port for connecting to play multi-player, and then how would i establish a connection with them. I thought i could just create a socket and just try to connect on every port, but how would i do that if i dont know the other computer ip address. On google i saw this question get asked several times, however none of the answers actually seemed helpful.
You will propably want to broadcast a message (broadcasts are received by all devices on the network). Then you would have the other machines listening fir such incoming broadcasts.
Basically in a broadcast you would advertise that a computer is running the program, and is willing to establish a direct connection. Then one of the computers would connect straight to the other, and you would work on from there.
EDIT: Someones similarily done aproach in java (blog post)
Sorry for kind of a dummy question, but I'm wondering how to work with WiFi connection via android. My application needs to transfer some data (both receiving and sending) with PC or with other android device using WiFi. How should I organize the process? I mean, how should I establish connection, then should I open a socket for data transfering, etc. Is there any way to do it without internet connection, smth like bluetooth, except wifi.p2p (which is only available for android 4.0)? Would be grateful for as detailed manual as possible.
Every network connection even if only in the local network or localhost reqieres the INTERNET permission.
Bluetooth and NFC might be an option, but I have no experiance with that.
I am developing an application which uses Bluetooth to connect to a device and send/receive data. I am doing all of my testing with a Nexus One phone.
I have never been able to establish a SPP (serial port) connection from my phone to any device. However, I have been able to connect from a device (my laptop) to my phone using a Mac equivalent of PuTTY (The only exception to this is the "Bluetooth File Transfer" app from the Marketplace seems to work, but I don't think that uses RFCOM/SPP...).
I keep seeing this message in my LogCat logs:
ERROR/BluetoothService.cpp(78): stopDiscoveryNative: D-Bus error in StopDiscovery: org.bluez.Error.Failed (Invalid discovery session)
as well as these:
java.io.IOException: Operation Canceled
java.io.IOException: Software caused connection abort
I have tried using the UUID of "00001101-0000-1000-8000-00805F9B34FB" and I have also tried using the:
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
sock = (BluetoothSocket) m.invoke(device, Integer.valueOf(1));
method instead of device.createRfcommSocketToServiceRecord(UUID); as well--with no luck.
I am using the BluetoothChat example and variations of that code to do all of my testing...
Solutions or suggestions would be great...or even a better/less complex example of some testing code I can run on the phone, or a python script or something I can run on my computer to help debug?
Thanks! I hope this isn't a bug with the Android OS, but if it is I hope to find a workaround.
EDIT: I should also note that most devices show up as "paired, but not connected" in the Bluetooth settings.
EDIT 2: The solution seems to be simply disabling any Bluetooth listening. See my answer post for more information.
The solution, as it turns out, was to disable the server functionality of the Bluetooth service. By only using createRfcommSocketToServiceRecord and never calling listenUsingRfcommWithServiceRecord (in the BluetoothChat example this means never starting the "AcceptThread") the problem was fixed.
Even though these two calls are supposed to be totally separated and have no affect on each other (according to the Android docs), simply commenting out listenUsingRfcommWithServiceRecord fixed my supposedly unrelated issue.
I can take the Bluetooth Chat program unedited and it will not be able to establish an outgoing connection to ANY bluetooth device I have tested (laptops, desktops, headsets, etc.), but if I remove that one thing it works flawlessly as a client.
Anyway, I hope this will help someone else if they come across the same issue. This must be a bug with the Android OS, or possibly the firmware on the Nexus One.
I would ignore the stopDiscovery error - its good that you're cancelling discovery before making your connection. Per the SDK docs:
Because discovery is a heavyweight
precedure for the Bluetooth adapter,
this method should always be called
before attempting to connect to a
remote device with connect().
Discovery is not managed by the
Activity, but is run as a system
service, so an application should
always call cancel discovery even if
it did not directly request a
discovery, just to be sure.
So with that said, were you able to get the Bluetooth Chat example to work before you made any modifications to the code?
The UUID you want for SPP/RFCOMM is:
static UUID UUID_RFCOMM_GENERIC = new UUID(0x0000110100001000L,0x800000805F9B34FBL);
or defined another way (both accomplish the same thing).
static final UUID UUID_RFCOMM_GENERIC = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");