I am programming an application where the owner of the application has to be able to send files to other available devices in the network. At this moment I am able to retrieve all the ip addresses of the devices that are connected to the network.
Is it possible to send files to these devices if i have their intern ip address
Current code:
InetAddress localhost = null;
try {
localhost = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// this code assumes IPv4 is used
byte[] ip = localhost.getAddress();
for (int i = 1; i <= 254; i++)
{
ip[3] = (byte)i;
InetAddress address = null;
try {
address = InetAddress.getByAddress(ip);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (address.isReachable(100))
{
System.out.println(address + " machine is turned on and can be pinged");
}
else if (!address.getHostAddress().equals(address.getHostName()))
{
System.out.println(address + " machine is known in a DNS lookup");
}
else
{
System.out.println(address + " the host address and host name are equal, meaning the host name could not be resolved");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You'll have to have something standing by on the target device or devices - an app that will receive the file. Alternatively , you may be able to share the file using built in components and hardware like Bluetooth.
Without help of server transfer over the internet is highly difficult. In some network it is not possible. only thing is you can transfer file to other device in LAN. Please look into this it might helpful
Related
Started working on a network monitoring app and I was wondering if there was a way to find out the ISP assigned IP address?
I've looked into the Inet and WifiManager API's and all they seem to give you is your local network ip address. The code I tried below, just gives me my local address.
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
TextView ipaddr = (TextView)findViewById(R.id.address);
ipaddr.setText("Your IP Address is: " + ip);
You make an HTTP call to a service that tells you what your external IP.
An example of such a service is ipify.
https://api.ipify.org/
Documentation:
https://www.ipify.org
Excerpt:
try (java.util.Scanner s = new java.util.Scanner(new java.net.URL("https://api.ipify.org").openStream(), "UTF-8").useDelimiter("\\A")) {
System.out.println("My current IP address is " + s.next());
} catch (java.io.IOException e) {
e.printStackTrace();
}
Try this:
try {
URL ip = new URL("http://checkip.amazonaws.com/");
BufferedReader in = new BufferedReader(new InputStreamReader(ip.openStream()));
System.out.println(in.readLine());
} catch (IOException e) {
e.printStackTrace();
}
I am trying to get some experience with Java network programming. So I made a simple text based game. This is how it looks on serverside:
try {
socket = new ServerSocket(PORT);
while(true) {
new ConnectedPlayer(socket.accept()).start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
And this is the client:
System.setProperty("java.net.preferIPv6Addresses","true");
try {
InetAddress ad = InetAddress.getByName("2a02:8070:b84:6b00:a1d1:30d7:346b:7c14");
socket = new Socket(ad, 9001);
output = socket.getOutputStream();
out = new PrintWriter(output);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
The address above is the Ipv6 address of the machine running
the server, I got this one by a website which detects my IP addresses,
it is different from what I get when I use ipconfig though, tried it with both.
When I tested both on the same machine with localhost, it worked.
However, now I wanted to try it on two different machines, one in a different network. Problem is, my internet provider apparently restricts me to something called "dual stack lite" which means my Server could only be reached over Ipv6 if I understand it correctly. But then, no port forwarding is needed there. When I test it now, it won't connect and gives a timeout after some time. I disabled firewalls on both machines.
When running a ServerSocket on a machine A with ip 145.74.217.109
And then trying to connect to machine A using machine B with ip 145.74.219.103 I am unable to connect.
But when using machine C with ip 145.74.217.180 it works.
Iam not sure if this is solvable in code or its just network settings. If It is network issues is there another way to go around this problem or would I need to go away from sockets to ...?
Machine A:
public void run() {
try {
sock = new ServerSocket(Constants.PORT);
for (;;) {
Socket newsock = sock.accept();
System.out.println("Accepting new player: ");
new PaintballPlayer(newsock);
}
} catch (Exception e) {
System.out.println("IO error " + e);
}
System.out.println("End!");
try {
sock.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Machine B, C :
socket = new Socket(ip, Constants.PORT);
if you look at the IP us server has IP 145.74.217.109 IP with 145.74.217.180 are able to connect while 145.74.219.103 is not being able to connect it means subnet 145.74.219.X has no access to 145.74.217.X that is why it is not being able to connect. It is network setting ask you network administrator for that. Make your both machine have same subnet mask
I am building an application which can transfer data between a mobile and a Wi-Fi device... The mobile has got the AP enabled (through code) and another device connects to this specific network... How can I detect through code to see the details of the devices connected to the network(AP)?** Is there a solution for this?
I have seen an application called Wifi Hot spot in HTC Desire that does this functionality of showing the IP addresses of the devices connected to the network. How can this be achieved?
Check out Review: Sprint Mobile Hotspot on HTC EVO 4G.
It shows an application that can actually display the connected users. How can we do that programmatically? Is there an API for that?
For creating an access point:
private void createWifiAccessPoint() {
if (wifiManager.isWifiEnabled())
{
wifiManager.setWifiEnabled(false);
}
Method[] wmMethods = wifiManager.getClass().getDeclaredMethods(); //Get all declared methods in WifiManager class
boolean methodFound = false;
for (Method method: wmMethods){
if (method.getName().equals("setWifiApEnabled")){
methodFound = true;
WifiConfiguration netConfig = new WifiConfiguration();
netConfig.SSID = "\""+ssid+"\"";
netConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
//netConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
//netConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
//netConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
//netConfig.preSharedKey = password;
//netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
//netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
//netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
//netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
try {
boolean apstatus = (Boolean) method.invoke(wifiManager, netConfig,true);
//statusView.setText("Creating a Wi-Fi Network \""+netConfig.SSID+"\"");
for (Method isWifiApEnabledmethod: wmMethods)
{
if (isWifiApEnabledmethod.getName().equals("isWifiApEnabled")){
while (!(Boolean)isWifiApEnabledmethod.invoke(wifiManager)){
};
for (Method method1: wmMethods){
if(method1.getName().equals("getWifiApState")){
int apstate;
apstate = (Integer)method1.invoke(wifiManager);
// netConfig = (WifiConfiguration)method1.invoke(wifi);
//statusView.append("\nSSID:"+netConfig.SSID+"\nPassword:"+netConfig.preSharedKey+"\n");
}
}
}
}
if(apstatus)
{
System.out.println("SUCCESSdddd");
//statusView.append("\nAccess Point Created!");
//finish();
//Intent searchSensorsIntent = new Intent(this,SearchSensors.class);
//startActivity(searchSensorsIntent);
}
else
{
System.out.println("FAILED");
//statusView.append("\nAccess Point Creation failed!");
}
}
catch (IllegalArgumentException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
if (!methodFound){
//statusView.setText("Your phone's API does not contain setWifiApEnabled method to configure an access point");
}
}
You could read the /proc/net/arp file to read all the ARP entries. See the example in the blog post Android: Howto find the hardware MAC address of a remote host. In the ARP table, search for all the hosts that belong to your Wi-Fi network based on the IP address.
Here is example code, which counts the number of hosts connected to the AP. This code assumes that one ARP entry is for the phone connected to the network and the remaining ones are from hosts connected to the AP.
private int countNumMac()
{
int macCount = 0;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("/proc/net/arp"));
String line;
while ((line = br.readLine()) != null) {
String[] splitted = line.split(" +");
if (splitted != null && splitted.length >= 4) {
// Basic sanity check
String mac = splitted[3];
if (mac.matches("..:..:..:..:..:..")) {
macCount++;
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try {
br.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
if (macCount == 0)
return 0;
else
return macCount-1; //One MAC address entry will be for the host.
}
You could ping the device if you know its host-name or its IP address.
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("ping -c 1 " + hostname);
proc.waitFor();
You could do an IP address scan, trying every IP address on the network for a response using a ping like above or trying to connect using TCP or UDP.
If you know the MAC address, you could use the ARP table.
If you got some own software running on the devices, you could send out UDP packets on every device and listen for them on your Android device. See Sending and receiving UDP broadcast packets in Android on how to do this.
You can use accesspoint:
WifiApControl apControl = WifiApControl.getInstance(context);
// These are cached and may no longer be connected, see
// WifiApControl.getReachableClients(int, ReachableClientListener)
List<WifiApControl.Client> clients = apControl.getClients()
This code works perfectly in Ubuntu, Windows, and Mac OS X. It also works fine with a Nexus One running Android 2.1.1.
I start sending and listening multicast datagrams, and all the computers and the Nexus One will see each other perfectly. Then I run the same code on a Droid (Firmware 2.0.1), and everybody will get the packets sent by the Droid, but the droid will listen only to its own packets.
This is the run() method of a thread that's constantly listening on a Multicast group for incoming packets sent to that group.
I'm running my tests on a local network where I have multicast support enabled in the router.
My goal is to have devices meet each other as they come online by broadcasting packages to a multicast group.
public void run() {
byte[] buffer = new byte[65535];
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
try {
MulticastSocket ms = new MulticastSocket(_port);
ms.setNetworkInterface(_ni); //non loopback network interface passed
ms.joinGroup(_ia); //the multicast address, currently 224.0.1.16
Log.v(TAG,"Joined Group " + _ia);
while (true) {
ms.receive(dp);
String s = new String(dp.getData(),0,dp.getLength());
Log.v(TAG,"Received Package on "+ _ni.getName() +": " + s);
Message m = new Message();
Bundle b = new Bundle();
b.putString("event", "Listener ("+_ni.getName()+"): \"" + s + "\"");
m.setData(b);
dispatchMessage(m); //send to ui thread
}
} catch (SocketException se) {
System.err.println(se);
} catch (IOException ie) {
System.err.println(ie);
}
}
This is the code that sends the Multicast Datagram out of every valid network interface available (that's not the loopback interface).
public void sendPing() {
MulticastSocket ms = null;
try {
ms = new MulticastSocket(_port);
ms.setTimeToLive(TTL_GLOBAL);
List<NetworkInterface> interfaces = getMulticastNonLoopbackNetworkInterfaces();
for (NetworkInterface iface : interfaces) {
//skip loopback
if (iface.getName().equals("lo"))
continue;
ms.setNetworkInterface(iface);
_buffer = ("FW-"+ _name +" PING ("+iface.getName()+":"+iface.getInetAddresses().nextElement()+")").getBytes();
DatagramPacket dp = new DatagramPacket(_buffer, _buffer.length,_ia,_port);
ms.send(dp);
Log.v(TAG,"Announcer: Sent packet - " + new String(_buffer) + " from " + iface.getDisplayName());
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e2) {
e2.printStackTrace();
}
}
Update (April 2nd 2010)
I found a way to have the Droid's network interface to communicate using Multicast: WifiManager.MulticastLock.
MulticastLock _wifiMulticastLock = ((WifiManager) context.getSystemService(Context.WIFI_SERVICE)).createMulticastLock("multicastLockNameHere");
_wifiMulticastLock.acquire();
Then when you're done...
if (_wifiMulticastLock != null && _wifiMulticastLock.isHeld())
_wifiMulticastLock.release();
After I did this, the Droid started sending and receiving UDP Datagrams on a Multicast group.
Update Jul-6-2010
Per request, here's my current code, the next method exists on an abstract class that can be used for both Broadcast and Multicast receivers.
public void run() {
onInit();
try {
byte[] data = new byte[65535];
while (isProcessing()) {
try {
DatagramPacket receivedDatagram = new DatagramPacket(data, data.length);
_socket.receive(receivedDatagram);
onDatagramReceived(receivedDatagram);
data = new byte[65535]; // This pattern is for saving memory allocation.
} catch (InterruptedIOException e) {
if (!isProcessing())
break;
}
} // while
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
} finally {
onStop();
_socket.close();
_socket.disconnect();
}
}
Your extending classes should implement onInit() and onDatagramReceived()
For a Multicast receiver, onInit() looks something like this:
_socket = new MulticastSocket(PORT_MULTICAST);
InetAddress groupAddress = InetAddress.getByAddress(MULTICAST_GROUP_ADDRESS);
InetAddress groupInetAddress = FrostWireUtils.fastResolveAddress(groupAddress); //reflection hack to not resolve ips
try {
_socket.setSoTimeout(500);
_socket.setTimeToLive(MULTICAST_TTL_GLOBAL);
_socket.setReuseAddress(true);
_socket.setNetworkInterface(
WifiUtils.getWifiNetworkInterface());
_socket.joinGroup(groupInetAddress);
WifiUtils.lockMulticast();
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}
I've implemented another test, this time using UDP Broadcast.
It works.
Conclusion: To the extent of my knowledge Motorola Droid phones on firmware 2.0.1 don't support multicast, but you can always use regular DatagramPackets on the broadcast address.