I am trying to connect to a my remote server from my Android device. How do I check if a specific port on my server is open? Eg. how to check if port 80 is open on my server 11.11.11.11?
Currently, I am using InetAddress to ping if the host is reachable but this does not tell me if the port 80 is open.
Current Code
boolean isAvailable = false;
try {
isAvailable = InetAddress.getByName("11.11.11.11").isReachable(2000);
if (isAvailable == true) {
//host is reachable
doSomething();
}
} catch (Exception e) {
}
Create a Socket that will check that the given ip with particular port could be connected or not.
public static boolean isPortOpen(final String ip, final int port, final int timeout) {
try {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(ip, port), timeout);
socket.close();
return true;
}
catch(ConnectException ce){
ce.printStackTrace();
return false;
}
catch (Exception ex) {
ex.printStackTrace();
return false;
}
}
Runtime.getRuntime().exec() and pass command to it to get various port entry with pid. Commands are below:
“cat /proc/net/tcp”, “cat /proc/net/tcp6”, “cat /proc/net/udp”, “cat /proc/net/udp6”.
Here is explanation with source code. I have tested it. :
http://kickwe.com/tutorial/android-port-scanner-tutorial/
Related
I have a client on a PC and a server on a tablet. I know the MAC addresses for both which means I do not do discoveries.
1. On the client if I use
connectString = "btspp://" + MACaddress + ":4;authenticate=false;encrypt=false;master=false";
It connects fine.
If I change the CN number (4) to anything else, it does not work. How is this number determined?
2. Everything works fine if the tablet is a Samsung with Android 5.0.2 When I use a Qunyico tablet with Android 10, it does not work. I get an error: Failed to connect; [10051] A socket operation was attempted to an unreachable network. What is the problem?
Client on PC – code taken from “Bluetooth-java-client-master”
public class IrcBluetoothClient {
private static void openConnection(String MACaddress) throws IOException {
// Tries to open the connection.
String connectString = "btspp://" + MACaddress + ":4;authenticate=false;encrypt=false;master=false";
StreamConnection connection = (StreamConnection) Connector.open(connectString);
if (connection == null) {
System.err.println("Could not open connection to address: " + MACaddress);
System.exit(1);
}
// Initializes the streams.
OutputStream output = connection.openOutputStream();
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(isr);
// Starts the listening service for incoming messages.
ExecutorService service = Executors.newSingleThreadExecutor();
service.submit(new IncomingMessagesLoggingRunnable(connection));
// Main loop of the program which is not complete yet
LocalDevice localDevice = LocalDevice.getLocalDevice();
while (true) {
String toSend = reader.readLine();
byte[] toSendBytes = toSend.getBytes(StandardCharsets.US_ASCII);
output.write(toSendBytes);
System.out.println("[" + localDevice.getFriendlyName() + " - " +
localDevice.getBluetoothAddress() + "]: " + toSend);
System.exit(1);
}
Server on tablet – code taken from https://developer.android.com/guide/topics/connectivity/bluetooth
private static final UUID A_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public BTacceptConnections( BluetoothAdapter mBluetoothAdapter) {
// Use a temporary object that is later assigned to mmServerSocket
// because mmServerSocket is final.
BluetoothServerSocket tmp = null;
try {
// A_UUID is the app's UUID string, also used by the client code.
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, A_UUID);
} catch (IOException e) {
Log.e(TAG, "Socket's listen() method failed", e);
}
mmServerSocket = tmp;
// Closes the connect socket and causes the thread to finish.
public void cancel(){
try {
mmServerSocket.close();
}catch (IOException e){
}
runFlag = 1;
}
//***********************************************************************************************
//
// This thread runs all the time listening for incoming connections.
//
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned.
while (runFlag == 0) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
Log.e(TAG, "Socket's accept() method failed", e);
break;
}
if (socket != null) { // If a connection was accepted
// A connection was accepted. Perform work associated with
// the connection in a separate thread.
// manageMyConnectedSocket(socket);
}else{
try {
mmServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
I know the MAC addresses for both which means I do not do discoveries.
Official Linux Bluetooth protocol stack BlueZ uses D-BUS API to establish bluetooth communication. If you check adapter-api, scanning will create device objects that you need to establish a communication which means discovering is not only done to retrieve MAC addresses only.
Your case might be the same, I would suggest doing discovery first.
I didn't find the right solution. The below code gives me local IP address (if I connected to Wifi, it gives IP address like 192.168.0.x), but I want public IP address (same as if I search in google " what is my IP ")
public static String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
return inetAddress.getHostAddress();
}
}
}
} catch (SocketException ex) {
ex.printStackTrace();
}
return null;
}
OR
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
Can anyone help? Thanks!
Step #1: Create a Web service that returns the requester's IP address
Step #2: Call that Web service from your app.
A device does not know its public IP address (unless that device was seriously misconfigured).
You may use the WS https://api.whatismyip.com/ip.php from whatismyip.com : This would output only your IP address in the simple text. (No input required, output is optional)
You must be a Gold Level Member to access the API
Updated Answer
You can make use of the web service from ipify.org
Read through the documentation here
Use https://api.ipify.org/?format=json WS to get device public IP address. This would output your IP address in JSON format.
You should use ipify because:
You can use it without limit (even if you're doing millions of requests per minute).
It's always online and available, and its infrastructure is powered by Heroku, which means that regardless of whether the server running the API dies, or if there's an enormous tornado which destroys half of the east coast, ipify will still be running!
It works flawlessly with both IPv4 and IPv6 addresses, so no matter what sort of technology you're using, there won't be issues.
....................
....................
I found this simple solution:
public String getExternalIpAddress() throws Exception {
URL whatismyip = new URL("http://checkip.amazonaws.com");
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(
whatismyip.openStream()));
String ip = in.readLine();
return ip;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Remember that this must be run on a separate thread.
You can do this with a simple thread.
you need to create a function in Activity.class file, and need to request a url that will give your public IP in text form: "https://api.ipify.org/. Click to open.
Add this function call in your onCreate() function.
getPublicIP();
Add this function in your MainActivity.class.
private void getPublicIP() {
new Thread(new Runnable(){
public void run(){
//TextView t; //to show the result, please declare and find it inside onCreate()
try {
// Create a URL for the desired page
URL url = new URL("https://api.ipify.org/"); //My text file location
//First open the connection
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(60000); // timing out in a minute
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
//t=(TextView)findViewById(R.id.TextView1); // ideally do this in onCreate()
String str;
while ((str = in.readLine()) != null) {
urls.add(str);
}
in.close();
} catch (Exception e) {
Log.d("MyTag",e.toString());
}
//since we are in background thread, to post results we have to go back to ui thread. do the following for that
PermissionsActivity.this.runOnUiThread(new Runnable(){
public void run(){
try {
Toast.makeText(PermissionsActivity.this, "Public IP:"+urls.get(0), Toast.LENGTH_SHORT).show();
}
catch (Exception e){
Toast.makeText(PermissionsActivity.this, "TurnOn wiffi to get public ip", Toast.LENGTH_SHORT).show();
}
}
});
}
}).start();
}
Make a call to a server like https://whatismyipaddress.com or http://howtofindmyipaddress.com/.
If you have the page source then parse the ip address out.
There are other servers who only return your ip address. Not a whole html page as above two. But i forgot which one...
I want to implement socket connection between 2 deceives , client keep sending GPS data to the server and I need both of it run in new thread , the client send first one data then keep show error like this
03-18 16:35:11.805: E/Client run:(8163): java.net.ConnectException: failed to connect to /192.168.2.103 (port 5678): connect failed: ECONNREFUSED (Connection refused)
here is the client code
public class Send implements Runnable{
private boolean Connect = true;
public void Connect(){
Connect = true;
}
public void Disconnect(){
Connect = false;
}
#Override
public void run() {
// TODO Auto-generated method stub
while(Connect){
try {
SocketClient = new Socket("192.168.2.103", 5678);
ObjectOutputStream oos = new ObjectOutputStream(SocketClient.getOutputStream());
oos.writeDouble(GPSinfo[2]);
//ObjectInputStream ois = new ObjectInputStream(SocketClient.getInputStream());
//ois.readInt();
oos.close();
//ois.close();
} catch (Exception e) {
Log.e("Client run: ", e.toString());
}
}
}
}
here is server code
public class Receive implements Runnable{
private boolean CanReceive = true;
private double Data;
public void Connect(){
CanReceive = true;
}
public void Disconnect(){
CanReceive = false;
}
#Override
public void run() {
// TODO Auto-generated method stub
while(CanReceive){
try {
SocketServer = new ServerSocket(5678);
Socket connectedSocket = SocketServer.accept();
ObjectInputStream ois = new ObjectInputStream(connectedSocket.getInputStream());
Data = ois.readDouble();
DataText.setText("" + Data);
//ObjectOutputStream oos = new ObjectOutputStream(connectedSocket.getOutputStream());
//oos.writeInt(1);
//ois.close();
//oos.close();
} catch (Exception e) {
Log.e("Server run: ", e.toString());
}
}
}
}
by the way , the both code is inner class , and INTERNET permission is added.
It's obvious it's not a router-firewall related problem as you are under the same net, so there are only a few possibilities:
There's nothing listening on that port on that IP on the server-side
There's a local firewall on the server-side that is blocking that connection attempt
You are not using WIFI so you're not under the same net.
You should make sure you can open that service some ther way, that would help you debugging where the culprit is. If you've already done this, I'd suggest using some debugging tool to trace TCP packets (I don't know either what kind of operating system you use on the destination machine; if it's some linux distribution, tcpdump might help, in Win environments WireShark works just good).
This isn't a 'data transfer error'. This is a 'connection refused' error. It means the server you want to transfer the data to or from isn't running at the IP:port you specified.
Try killing the adb service before you begin the connection. I had a similar problem and killing the adb service before the connection resolved the issue.
I had the same error. I simply used ServerSocket and it worked well.
ServerSocket socket = new ServerSocket(8888);
I'm trying to establish a bluetooth communication between an android phone/tablet (4.0.3), and a bluetooth device, which is an earring reader (Destron Fearring DTR3E, in case you want to know, which I don't suppose you do).
I paired the phone with the reader (the reader has the pairing passcode on a tag) from the bluetooth settings, bluetooth is on of course, and now I'm trying to listen to reads from the device, by means of BluetoothServerSocket. The problem is that the accept call never returns, so obviously I am doing something wrong. The communication is done using RFCOMM.
Code:
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
String uuid = "00001101-0000-1000-8000-00805F9B34FB";
tmp = bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord("pdfParserServer", UUID.fromString(uuid));
} catch (Exception e) {
e.printStackTrace();
}
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
try {
mmServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) { }
}
}
Is there something I am missing?
Thank you!
The only reason that could cause the code never to come back from accept is that, the device "Destron Fearring DTR3E" you are trying to connect to, has actually a bluetoothserver socket and not a bluetooth client, hence, the device might be waiting for you to actually connect to it, in stead of you creating a bluetoothserver socket and waiting for it to connect to your android device, you should read the specs on the device and make sure that actually is you the one that has to open a connection on "Destron Fearring DTR3E" socket...
Hope this helps...
Regards!
I have to network devices:
1. Server (variable IP) that needs to receive a String for further stuff (e.g. Socket 9999). This server has also another socket (e.g. 8888) where it sends it's device name on pairing.
2. Client (variable IP) that does NOT know the IP of the server but wants to send him the string.
On a IP C-network I could iterate through the last octet (0..255) and check if Socket 8888 transmits something. But on A and B networks I have no chance. Is there any other solution for this? (I could iterate through all four octets but that wouldn't be an elegant solution).
Thank you!
The most appropriate way to do it, if they are in the same LAN is:
Client sends a UDP broadcast to a specific port and matching the network class (A,B,C)
Server is listening on this port, receives the broadcast packet and connect or send his IP to the client.
With just two network packets you know the IP address.
--EDITED--
To broadcast:
InetAddress broadcastAddr = SharedFunctions.getNetworkLocalBroadcastAddressdAsInetAddress();
DatagramSocket socket = null;
try {
socket = new DatagramSocket();
socket.setBroadcast(true);
System.arraycopy(BROADCAST_SIGNATURE, 0, buffSend, 0, BROADCAST_SIGNATURE.length);
DatagramPacket packet = new DatagramPacket(buffSend, buffSend.length, broadcastAddr, BROADCAST_PORT);
socket.send(packet);
} catch (Exception e) {
e.printStackTrace();
if(socket != null) try {socket.close();} catch (Exception e1) {}
}
public static InetAddress getNetworkLocalBroadcastAddressdAsInetAddress() throws IOException {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
if(VERSION.SDK_INT < 9) {
if(!intf.getInetAddresses().nextElement().isLoopbackAddress()){
byte[] quads = intf.getInetAddresses().nextElement().getAddress();
quads[0] = (byte)255;
return InetAddress.getByAddress(quads);
}
}else{
if(!intf.isLoopback()){
List<InterfaceAddress> intfaddrs = intf.getInterfaceAddresses();
return intfaddrs.get(0).getBroadcast(); //return first IP address
}
}
}
return null;
}
To receice broadcast:
try {
socketReceiver = new DatagramSocket(BROADCAST_PORT);
socketReceiver.setBroadcast(true);
DatagramPacket packet = new DatagramPacket(buffRecv, buffRecv.length);
while(Thread.currentThread() == cThreadReceiver){
socketReceiver.receive(packet);
//here you receive the packet and can check the sender IP address
}
} catch (Exception e) {
e.printStackTrace();
if(socketReceiver != null) try {socketReceiver.close();} catch (Exception e1) {}
}
You will need to do some editing but should start you in the right track.