I'll try to be as descriptive as possible
I'm new to android and i'm making an android application
In that application i'd like to be able to see the address of the HTTP requests going OUT from the mobile (On what website they are heading).
So i've looked around and i found out that to do that , I need to use a VPN and android 4.0+ has a VPNService supplied from google implemented using ToyVPNService
So i got this service and started changing in it so i can use it without the need of using a server
I'd like to work the VPN as follows:
1-Capture the HTTP requests
2-Read their destination
3-Resend them back to their way
So i took the VPNService and i started modifying it so that i don't need an actual server
Here's the code i'm using
package com.example.testingservice;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.net.VpnService;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.widget.Toast;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.util.Enumeration;
public class SO1 extends VpnService implements Handler.Callback, Runnable {
private static final String TAG = "ToyVpnService";
private Handler mHandler;
private Thread mThread;
private ParcelFileDescriptor mInterface;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// The handler is only used to show messages.
if (mHandler == null) {
mHandler = new Handler(this);
}
// Stop the previous session by interrupting the thread.
if (mThread != null) {
mThread.interrupt();
}
// Start a new session by creating a new thread.
mThread = new Thread(this, "ToyVpnThread");
mThread.start();
return START_STICKY;
}
#Override
public void onDestroy() {
if (mThread != null) {
mThread.interrupt();
}
}
#Override
public boolean handleMessage(Message message) {
if (message != null) {
Toast.makeText(this, message.what, Toast.LENGTH_SHORT).show();
}
return true;
}
#Override
public synchronized void run() {
Log.i(TAG,"running vpnService");
try {
runVpnConnection();
} catch (Exception e) {
e.printStackTrace();
//Log.e(TAG, "Got " + e.toString());
} finally {
try {
mInterface.close();
} catch (Exception e) {
// ignore
}
mInterface = null;
mHandler.sendEmptyMessage(R.string.disconnected);
Log.i(TAG, "Exiting");
}
}
private boolean runVpnConnection() throws Exception {
configure();
FileInputStream in = new FileInputStream(mInterface.getFileDescriptor());
// Allocate the buffer for a single packet.
ByteBuffer packet = ByteBuffer.allocate(32767);
// We keep forwarding packets till something goes wrong.
while (true) {
// Assume that we did not make any progress in this iteration.
boolean idle = true;
// Read the outgoing packet from the input stream.
int length = in.read(packet.array());
if (length > 0) {
Log.i(TAG,"************new packet");
System.exit(-1);
while (packet.hasRemaining()) {
Log.i(TAG,""+packet.get());
//System.out.print((char) packet.get());
}
packet.limit(length);
// tunnel.write(packet);
packet.clear();
// There might be more outgoing packets.
idle = false;
}
Thread.sleep(50);
}
}
public 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();
Log.i(TAG,"****** INET ADDRESS ******");
Log.i(TAG,"address: "+inetAddress.getHostAddress());
Log.i(TAG,"hostname: "+inetAddress.getHostName());
Log.i(TAG,"address.toString(): "+inetAddress.getHostAddress().toString());
if (!inetAddress.isLoopbackAddress()) {
//IPAddresses.setText(inetAddress.getHostAddress().toString());
Log.i(TAG,"IS NOT LOOPBACK ADDRESS: "+inetAddress.getHostAddress().toString());
return inetAddress.getHostAddress().toString();
} else{
Log.i(TAG,"It is a loopback address");
}
}
}
} catch (SocketException ex) {
String LOG_TAG = null;
Log.e(LOG_TAG, ex.toString());
}
return null;
}
private void configure() throws Exception {
// If the old interface has exactly the same parameters, use it!
if (mInterface != null) {
Log.i(TAG, "Using the previous interface");
return;
}
// Configure a builder while parsing the parameters.
Builder builder = new Builder();
String SS=getLocalIpAddress();
builder.setMtu(1500);
// builder.addAddress("10.0.0.2", 24);
builder.addAddress(SS, 24);
// builder.addAddress(SS,24);
builder.addRoute("0.0.0.0",0);
try {
mInterface.close();
} catch (Exception e) {
// ignore
}
mInterface = builder.establish();
}}
The problem is this line
mInterface = builder.setSession("GITVPN").setConfigureIntent(mConfigureIntent).establish();
the Establish returns NULL and i can't seem to get it working
I'm thinking there is a problem with the addresses
I'd like to work it that there's no server , and there would be a tunnel that reads the packets
I've seen some other post that said i should make the addresses to 10.0.0.2 instead of external ips ( 192.168.x.x) and i should add route (0.0.0.0,0)
However the descriptor file keeps returning null and i can't seem to fix it
Any help will be appreciated , and sorry if this sounded that it was repeated but i'm super stuck and you guys are my only hope
You can't run the VpnService and establish a VPN connection without having a server that you communicate with and forwards the traffic to the internet.
Check the IP address you assigned to the interface, it should not be the same as other adapters.
What the builder operated on is a TUN device, which is created for VPN service.
So, IP address of the TUN should be proper set.
Make the address conflict with others is not a good idea.
Also, Step 3 you mentioned is not quite easy as Android not support raw socket.
just to revive an old thread...
VpnService requires a users interaction to start and won't work without it
the ToyVpnClient puts a button on the screen that the user has to click and once that's done, the Builder method will return the interface
so, steps to make it work are;
1. build a button on your app
2. onclick of that button, call VpnService.prepare(this); (this = your app context)
3. Builder.establish() will now return a VPN interface
Related
I get bit problem, The problem is as follows:
At server socket, server receive data type as byte array:
this.receiveStream = new DataInputStream(this.clientSocket.getInputStream());
byte[] receiveBuffer = new byte[bufferSize];
while (this.receiveStream.read(receiveBuffer, 0, receiveBuffer.length) > -1) {
String dataReceive = new String(receiveBuffer, StandardCharsets.UTF_8).trim();
}
If client send text message in one thread then server run well, but if client run >=2 thread concurrent to send text message then at server, the message were mixed, it mean clientThead1 send "ABC", clientThead2 send "XYZ" => server receive "AXBC" OR "AXYZ",... => It is not expected message.
How to solve this problem???
P/S: I have tested with server receive message as text, it work well:
while (true) {
String dataReceive = this.receiveStream.readUTF().trim();
}
But i can not use it, because server serve muti platform client, so i want to server use byte array to receive data
Thanks all,
UPDATE:
I can not post full code because it is very long character
This is link all code Client + Server:https://www.mediafire.com/folder/j4d041uqfowt6/SocketApp
Do you use TCP or UDP? It is important, the sockets do not hide the difference.
For TCP,
the client threads must not reuse the same connection.
Each client thread must open its own connection, as if it were applications on different devices.
The server must start a new thread each time it listening socket receives a job. That thread will use its own connection; threads servicing different clients are independent as if it were applications on different devices.
I think you see the logic: one client thread <--> one service thread.
(I think you know that a listening socket does not receive data, it creates a data socket).
For UDP, on the server side you have to distinguish the clients yourself.
It would not be possible if you were sending single bytes, but packets are not single bytes, UDP packets include auxiliary information. You have the sender's IP and port, so you can distinguish the clients if they are not two threads using the same port on the same IP.
Use a child thread to read data from socket and main thread to accept request and hand over to child..
Server
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Server extends Thread {
public Server(String ip, int port) {
try {
ServerSocket ser = new ServerSocket(port);
System.out.println("Listening....");
while (true) {
Socket soc = ser.accept();
new Child(soc).start();
System.out.println("Child Started...");
}
} catch (IOException e) {
}
}
private class Child extends Thread {
Socket cSoc;
public Child(Socket soc) {
this.cSoc = soc;
}
#Override
public void run() {
try {
String data = "";
InputStream in = cSoc.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
int ch = 0, cnt = 0;
byte[] buffer = new byte[1024];
int length = Integer.parseInt(br.readLine());
System.out.println("Message Length = " + length);
while ((ch = in.read(buffer)) != -1) {
data += new String(buffer);
cnt += ch;
if (cnt >= length) {
break;
}
}
System.out.println("Message = " + data);
} catch (IOException ex) {
}
}
}
public static void main(String[] args) {
new Server("localhost", 1234).start();
}
}
Client
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
public class Client {
public static void main(String[] args) {
try {
Socket s = new Socket("localhost", 1234);
OutputStream o = s.getOutputStream();
PrintStream ps = new PrintStream(o);
String data = "your data";
ps.println(data.length());
Thread.sleep(100);
o.write(data.getBytes());
ps.close();
o.close();
} catch (Exception e) {
}
}
}
It's just a sample implementation you can wrap the concept.
I'm working on a simple vehicle project, made with Arduino Uno and controlled by an Android App.
My matter is to send continuous stream from the app to my bluetooth module (HC-06) on Arduino.
I did it with onTouch events and a new thread called from my main activity, but something is obviously wrong because the app seems to send each command as i want it to do, but the Arduino waits until the finger is off the button and receives all data (from action.down to action.up) at a time.
To understand :
I update a small string like this "1255090" each time a command button is action.down or action_move, convert it to bytes and send it via bluetooth.
If i briefly click on the button, Arduino will receive the correct string "1255090", but if i maintain my finger on the button, Arduino waits for the string, and when i release the button, Arduino receives for example "125509012540901253090125209012510901252090" (depending on how long i clicked).
Android activity (partial)
drive.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent m) {
if (m.getAction() != MotionEvent.ACTION_UP) {
accelerer(); // inscreases the speed
str_flux(); // constructs the string
byte[] bytes = new byte[0];
try { bytes = flux.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); }
sendReceiveBT.write(bytes); // calls the thread's method
} else{ralentir();}
return true;
}
});
Thread
package com.*.vehicle.util;
import android.bluetooth.BluetoothSocket;
import android.util.Log;
import java.io.IOException;
import java.io.OutputStream;
public class SendReceiveBytes implements Runnable {
private BluetoothSocket btSocket;
private OutputStream btOutputStream = null;
String TAG = "SendReceiveBytes";
public SendReceiveBytes(BluetoothSocket socket) {
btSocket = socket;
try { btOutputStream = btSocket.getOutputStream(); } catch (IOException streamError) { Log.e(TAG, "Error when getting input or output Stream"); }
}
public void run() {
byte[] buffer = new byte[1024];
int bytes;
}
public void write(byte[] bytes) {
try {
btOutputStream.write(bytes); // Send the bytes to Arduino
btOutputStream.flush(); // don't know if it really does something...
Log.e(TAG, "SUCCESS !");
}
catch (IOException e) {
Log.e(TAG, "Error when writing to btOutputStream");
}
}
}
Arduino loop
void loop() {
s = Serial.readString(); // 1255090
if (s!=""){
Serial.println(s);
bt_direction = s.substring(0,1).toInt();
bt_speed = s.substring(1,4).toInt();
bt_angle = s.substring(4,7).toInt();
s = "";
} else{
if (bt_speed>0){
for(int i=bt_speed;i>=0;i--){bt_speed--;}
}
else{ bt_speed = 0; }
}
if (bt_direction==1){bt_dir = true;} else{bt_dir = false;}
if (bt_speed==0){stop_motor();} else{dc_motor(bt_speed, bt_dir);}
Serial.println(bt_direction);
servo_turn(bt_angle);
}
If I am getting you correctly, you can easily handle it using multiple states.
For example,
State1: 123456: is for tap,
State2: 123457: is for press & hold,
State3: 123458: is for release,
And so on.
And in you ui detect whether user is tapping or press and hold.
If press and hold , instruct arduino to do something until receives release.
In this way you can even handle the situation without continuously sending bit, And as per my understanding you don't need this.
Correct me if I am wrong.
Thanks !!!
I'm using the library Jamod and I have trouble reading the record, what I want is to read only the record number 300 PLC I'm connected, but I get read error (enters the catch). Thanks for your help
package com.JR.scada;
import java.net.InetAddress;
import net.wimpi.modbus.Modbus;
import net.wimpi.modbus.io.ModbusTCPTransaction;
import net.wimpi.modbus.msg.ReadInputDiscretesRequest;
import net.wimpi.modbus.msg.ReadInputDiscretesResponse;
import net.wimpi.modbus.msg.ReadMultipleRegistersResponse;
import net.wimpi.modbus.net.TCPMasterConnection;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class Main extends Activity{
TextView text, depurar;
EditText IP;
Button boton;
int i=0;
TCPMasterConnection con = null; //the TCP connection
ModbusTCPTransaction trans = null; //the Modbus transaction
InetAddress addr = null; //direccion del esclavo
int port = Modbus.DEFAULT_PORT;//puerto por defecto 502
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.lblRegistro);
IP = (EditText) findViewById(R.id.txtIp);
depurar = (TextView) findViewById(R.id.txtdepurar);
boton = (Button)findViewById(R.id.btnVerRegistro);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
protected void onStop() {
super.onStop();
//Close the TCP connection
con.close();
}
public class conectar extends AsyncTask<String,String,Integer>{
ReadInputDiscretesRequest req = null; //the request
ReadInputDiscretesResponse res = null; //the response
int startReg;
protected void onPreExecute() {
try {
//IP address;
addr = InetAddress.getByName("212.170.50.238");
} catch (Exception e) {
Log.d("MODBUS","IP error", e);
}
}
protected Integer doInBackground(String... urls) {
try {
// Open the connection
con = new TCPMasterConnection(addr);
con.setPort(port);
con.connect ();
try {
startReg = 300;
// Prepare the request
req = new ReadInputDiscretesRequest (startReg, 1);
// Prepare the transaction
trans = new ModbusTCPTransaction(con);
trans.setRequest(req);
// execute the transaction
trans.execute();
// get the response
res = (ReadInputDiscretesResponse) trans.getResponse ();
} catch (Exception e) {
Log.d("MODBUS", "Error in reading/writing");
return 1;
}
} catch (Exception e) {
Log.d("MODBUS","connection error", e);
return 1;
}
return 0;
}
protected void onPostExecute(Integer bytes) {
if(con.isConnected()){
depurar.setText("conecta");
}
text.setText("Digital Inputs Status=" + res.getDiscretes ().toString () );
}
}
public void onClick(View v) {
// int startReg;
conectar conectamos = new conectar();
conectamos.execute("hola");
}
error:
08-21 10:01:57.554: D/MODBUS(3322): Error in reading/writing
Without knowing more about the modbus configuration on your slave PLC, my first suggestion is to try a different value for startReg, and see if the error persists. This will rule out problems with your Java.
Some test numbers that should work: 0,1,7,8
They may not all work, but at least one of them should return successfully.
If none of them return successfully, there may be a problem on the PLC configuration, or a problem with your request code.
If one of the test numbers is successful, you should post your results. If so, this means that you are attempting to access a memory location that does not exist on the PLC. If you access undefined PLC memory locations, often the PLC will abort the request (it does not just send back '0').
Followup remarks:
If you find that your code works when using different values for startReg, but not for 300, the reason has to do with memory mapping on the PLC, and this can be different for each brand/model of PLC (post your PLC brand/model if available).
You say in your question 'record 300'. When working with PLC, you usually don't refer to memory as a record. Are you trying to access Bit 300, Byte 300, Word 300, DoubleWord 300?
The real question you need to be asking, is 300 the actual modbus address you want to read, or is 300 how the PLC address is mapped (such as the 300th I/O slot, not necessarily the 300th WORD). It may be required to convert between octal, decimal, and hexidecimal addresses. Or, you may need to re-index an address (some PLCs like to start counting at 1, but generally modbus starts counting at 0).
Perhaps you meant to read BIT 300 (not record 300), which would then be 12th BIT in the 18th WORD, so it would look like this:
//
startReg = 17;
// Prepare the request
// Your 300th bit should be the last value returned.
req = new ReadInputDiscretesRequest (startReg, 12);
The different values I suggested for startReg are meant to help you discover how your PLC Inputs are mapped into modbus addresses by your Java library. This might help with number conversions.
If you keep getting exceptions in your catch block, you might want to find out more about the error.
Try changing this line from your original code:
try {
//...
} catch (Exception e) {
Log.d("MODBUS", "Error in reading/writing");
return 1;
}
into this:
try {
//...
} catch (Exception e) {
Log.d("MODBUS", e.getMessage() );
return 1;
}
Hopefully the exception will tell you more about exactly why its failing. Post those results.
If you are getting a NULL message, you might try using a debugger to manually inspect your connection instance.
I'm trying to send a UDP packet to a server to see if it is online. I have made a stand alone app to do exactly that and it works without a problem but when putting the code in the app and calling the function it throws an exception when it goes to actually send the packet. I have done a lot of research and I can't find any reason why. I replaced the IP with a fake one because I don't want to post the actual IP. Thanks for the help in advanced.
import java.io.IOException;
import java.net.*;
import android.app.Activity;
public class CheckStatus extends Activity {
//Check if the server is online
public static boolean check() {
try {
byte[] receiveData = new byte[1024];
InetAddress address = InetAddress.getByName("11.11.11.11");
//create socket
DatagramSocket clientSocket = new DatagramSocket();
//set timeout
clientSocket.setSoTimeout(1000);
//send packet
DatagramPacket p = new DatagramPacket(Integer.toBinaryString(0x0006000000).getBytes(), 5, address, 44462);
clientSocket.send(p);//throws exception here
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
clientSocket.close();
return true;
} catch (Exception e) {
return false;
}
}
}
When printing the exception i got "android.os.NetworkOnMainThreadException"
Declare this asyncTask in the activity and call your check() method from there.
EDIT:
private class CheckStatusTask extends AsyncTask<Object, Object, Boolean> {
protected Boolean doInBackground(Object... arg0) {
boolean flag = check();
return flag;
}
protected void onPostExecute(Boolean flag) {
// use your flag here to check true/false.
}
}
And make this call :
new CheckStatusTask().execute();
Reference :
Painless threading
I want to transfer messages from the android device to desktop application. My question is that can i connect the android WiFi device with the desktop WiFi device without any use of internet connection. I want to use it just like the Bluetooth. is this possible or not? if it is possible then how can i implement it?
Thanks and Regards
Amit Thaper
Here is an implementation of mreichelt's suggestion. i looked this up when i had the same problem and figured i'd just post my implementation of the solution. it's really simple. i also built a java server that listens for incoming requests from the android device (for debugging purposes mostly). here's the code to send stuff over the wireless:
import java.net.*;
import java.io.*;
import java.util.*;
import android.app.Activity;
import android.content.Context;
import android.content.ContentValues;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.util.Log;
public class SMSConnection {
/* The socket to the server */
private Socket connection;
/* Streams for reading and writing the socket */
private BufferedReader fromServer;
private DataOutputStream toServer;
/* application context */
Context mCtx;
private static final String CRLF = "\r\n";
/* Create an SMSConnection object. Create the socket and the
associated streams. Initialize SMS connection. */
public SMSConnection(Context ctx) throws IOException {
mCtx=ctx;
this.open();
/* may anticipate problems with readers being initialized before connection is opened? */
fromServer = new BufferedReader(new InputStreamReader(connection.getInputStream()));
toServer = new DataOutputStream(connection.getOutputStream());
}
public boolean open(String host, int port) {
try {
connection = new Socket(host, port);
return true;
} catch(IOException e) {
Log.v("smswifi", "cannot open connection: " + e.toString());
}
return false;
}
/* Close the connection. */
public void close() {
try {
connection.close();
} catch (IOException e) {
Log.v("smswifi","Unable to close connection: " + e.toString());
}
}
/* Send an SMS command to the server. Check that the reply code
is what is is supposed to be according to RFC 821. */
public void sendCommand(String command) throws IOException {
/* Write command to server. */
this.toServer.writeBytes(command+this.CRLF);
/* read reply */
String reply = this.fromServer.readLine();
}
}
that's a basic skeleton for a connection class. you simply instantiate the class, and call open on the instance you create with the host and port (don't forget to close the connection when you're done) and you can change the body of sendCommand to your liking. i've included a read/write operation in the function body as an example.
here is the code to run a server on a remote machine that listens for connections and spawns a thread to handle each request. it can easily interact with the above code for debugging (or any use).
import java.io.*;
import java.net.*;
import java.util.*;
public final class smsd {
///////MEMBER VARIABLES
ServerSocket server=null;
Socket client=null;
///////MEMBER FUNCTIONS
public boolean createSocket(int port) {
try{
server = new ServerSocket(port);
} catch (IOException e) {
System.out.println("Could not listen on port "+port);
System.exit(-1);
}
return true;
}
public boolean listenSocket(){
try{
client = server.accept();
} catch (IOException e) {
System.out.println("Accept failed: ");
System.exit(-1);
}
return true;
}
public static void main(String argv[]) throws Exception {
//
smsd mySock=new smsd();
//establish the listen socket
mySock.createSocket(3005);
while(true) {
if(mySock.listenSocket()) {
//make new thread
// Construct an object to process the SMS request message.
SMSRequest request = new SMSRequest(mySock.client);
// Create a new thread to process the request.
Thread thread = new Thread(request);
// Start the thread.
thread.start();
}
}
//process SMS service requests in an infinite loop
}
///////////end class smsd/////////
}
final class SMSRequest implements Runnable {
//
final static String CRLF = "\r\n";
Socket socket;
// Constructor
public SMSRequest(Socket socket) throws Exception
{
this.socket = socket;
}
// Implement the run() method of the Runnable interface.
public void run()
{
try {
processRequest();
} catch (Exception e) {
System.out.println(e);
}
}
private static void sendBytes(FileInputStream fis, OutputStream os) throws Exception
{
// Construct a 1K buffer to hold bytes on their way to the socket.
byte[] buffer = new byte[1024];
int bytes = 0;
// Copy requested file into the socket's output stream.
while((bytes = fis.read(buffer)) != -1 ) {
os.write(buffer, 0, bytes);
}
}
private void processRequest() throws Exception
{
// Get a reference to the socket's input and output streams.
InputStream is = this.socket.getInputStream();
DataOutputStream os = new DataOutputStream(this.socket.getOutputStream());
// Set up input stream filters.
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
// Get the request line of the SMS request message.
String requestLine = br.readLine();
//print message to screen
System.out.println(requestLine);
//send a reply
os.writeBytes("200");
// Close streams and socket.
os.close();
br.close();
socket.close();
}
}
nb4namingconventions.
almost forgot. you will need to set these permissions inside the tags in your AndroidManifest.xml in order to use wireless.
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
This is easily possible if both devices are using the same wifi network and can ping each other. You may just create a Java application on your desktop which creates a ServerSocket. Then you can open a Socket in your Android app using the desktop's IP address and send data through the OutputStream.
I believe that Amit is referring to having the machines connect directly to each other using wireless.
There is the development currently of the Wifi-direct specification to allow for Plug-in-Play setup of Access Points. The issue currently is ensuring one of the machines is an AP that other machine(s) can establish connection to.
I'm interested in how this relates to Ad-Hoc networks. I don't have a solution, however I am quite interested in this question too ! (Assuming this is your question Amit).