Android send string over 3g - android

I'm trying to send a simple string from an android device to a pc.
I managed to send the string via wifi (because is on a LAN network), but the code doesn't work over 3g.
The code i'm using is this:
class send extends AsyncTask
{
#Override
protected Object doInBackground(Object... params) {
try {
InetAddress serverAddr = InetAddress.getByName("IP here")
Socket socket = new Socket(serverAddr, 8564);
String message = "sample_message";
try {
PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
out.println(message);
} catch(Exception e) {}
finally {
socket.close();
}
} catch (Exception e) {}
return null;
}
}

Where is your PC connected? Is it a LAN behind NAT? Are you using the LAN IP address as serverAddr? What is "IP here"?
If you are using a local network IP address behind the NAT you'll never be able to connect.
If you have a router/wifi AP, enable port forwarding to you PC and use the public IP address provided by the ISP as serverAddr.

Have you tried creating a DataOutputStream like
DataOutputStream dos=new DataOutputStream(socket.getOutputStream());
dos.writeBytes(message + '\n');
Instead of :
PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
out.println(message);

Related

Problems writing to network device using sockets

I have a wireless device communicating over port 22 connected to my network. Once the device starts up, it immediately starts sending log data. Once this device is sent a command, it stops logging and responds accordingly. This all works, I have tested it using a telnet client.
My problem is that I can't seem to send it a command properly in my app. I am reading the log data as planned, but when I send it a command, in this case the command "r", it continues outputting log data instead what it should be showing me for that particular command. This has to mean that I am not properly sending the command. This is my code for the task that sends it the command and logs the output in the android logcat:
public class ReceiveVarTask extends AsyncTask<Void, Void, Void>{
String dstAddress;
int Port;
ReceiveVarTask(String addr, int port) {
dstAddress = addr;
Port = port;
}
protected Void doInBackground(Void... vars){
Socket socket = null;
String command = "r";
try {
Log.i(TAG, "Connecting to port 22");
socket = new Socket(dstAddress, Port);
Log.i(TAG, "Connected to port 22");
PrintWriter writer = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
InputStream inputStream = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
writer.println(command);
String line = reader.readLine();
Log.i(TAG, line);
while(line!=null && !isCancelled()){
line = reader.readLine();
Log.i(TAG, line);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
protected void onPostExecute(Void arg) {
taskRunning = false;
}
}
What am I doing wrong? Why is it not registering the command?
UPDATE:
I have used several telnet clients for testing, and the server is reading the 'r' command as expected on some. It works using a windows telnet client, and it works using the vSSH app by Velestar. Interestingly enough, when testing this with the android telnet client by ClockworkMod, the server is not registering the command either.
Could it be something to do with encoding?
Do I need any additional permissions to work with sockets? I have android.permission.INTERNET declared in the manifest.
UPDATE 2:
The developer of of the hardware just told me that the hardware is expecting the command to be ASCII encoded and CR terminated. So I will try changing PrintWrite initialization to:
PrintWriter writer = new PrintWriter(new BufferedWriter( new OutputStreamWriter(socket.getOutputStream(), "ASCII")), true);
and the print command to:
writer.print(command+"\r");
Changing the the encoding type to "US-ASCII" and adding a carriage return instead of a new line did the trick. I'm able to read and write data as expected.
From my understanding of your problem description, you have a telnet server, and when a telnet client connects to that server, the server start sending the client log data. The client may send an "r" to the server to stop the log stream.
I suggest you first confirm using another telnet client that sending an "r" does stop the server from generating more log data.
You could use Wireshark to check if the "r" command is indeed sent.

Peer to peer data sharing using Wi-Fi direct

I am developing an Android multiplayer game using Wi-Fi direct.
Using Wi-Fi direct, I am able to establish connection between peer devices. Also the code is able to send the data from client device to server device. (According to Android documentation, the Wi-Fi direct uses client-server model)
Problem:
I am not able to share the data from server device to client device using Wi-Fi direct.
I have following questions:
Is there any other way to transfer data (bi-directional) between two
Android devices which are connected through Wi-Fi Direct?
During my online research I understood that to send data from server
device to client device, server needs to know the client’s IP
address. How to use this client’s IP address to send data from
server device to client device? (I am able to fetch the client’s IP
address)
I'd appreciate any suggestions on these queries. Thank you in advance.
Code:
Server Side
public class DataTransferAsyncTask extends AsyncTask<Void,Void,String>{
ServerSocket serverSocket;
Socket client;
InputStream inputstream;
Context context = mActivity.getApplicationContext();
String s;
InetAddress client_add;
#Override
protected String doInBackground(Void... voids) {
try{
serverSocket = new ServerSocket(9999);
Log.e("hello", "Server: Socket opened");
client = serverSocket.accept();
Log.e("hello", "Server: connection done");
inputstream = client.getInputStream();
// OutputStream outputStream = serverSocket.getO
//getting data from client
byte[] address = new byte[12];
if(client.isConnected())
inputstream.read(address);
s = new String(address);
String only_add = new String();
only_add = s.substring(0,12);
client_add = InetAddress.getByName(only_add);
Log.e("hello", "Server: clients ip 1 " + only_add);
Log.e("hello", "Server: converted address 1 " + client_add + " \n is connected"+
client.isConnected());
//send data to client
OutputStream stream = client.getOutputStream();
stream.write(s.getBytes());
Log.e("hello","context value "+context);
// cancel(true);
}catch (IOException e){
}
return null;
}
}
Client Side:
#override
protected void onHandleIntent(Intent intent) {
Log.e("hello","client socket");
Toast.makeText(this,"client socket",Toast.LENGTH_LONG).show();
Context context = getApplicationContext();
if(intent.getAction().equals(action_send_data)){
String host = intent.getStringExtra(group_owner_address);
Socket socket = new Socket();
int port = intent.getIntExtra(group_owner_port,9999);
//binding connection
try{
String x="hello";
Log.e("hello","opening client socket");
byte[] address = getLocalAddress();
String ipAdd = getDottedDecimalIP(address);
socket.bind(null);
socket.connect(new InetSocketAddress(host,port),socket_timeout);
Log.e("hello","device socket address "+ socket.getInetAddress() );
Log.e("hello","client socket is connected"+socket.isConnected());
Log.e("hello","device address :"+ipAdd + " byte "+ address);
//sending data to server
OutputStream stream = socket.getOutputStream();
stream.write(ipAdd.getBytes());
//getting data from the server(supposed to)
InputStream inputstream = socket.getInputStream();
byte[] address_to_sto_fr_ser = new byte[15] ;
inputstream.read(address_to_sto_fr_ser);
String s = new String(address_to_sto_fr_ser);
Log.e("msg from server","msg from server "+s);
// stream.close();
// is.close();
}catch (IOException e){
}
}
}
The communication between client and WiFi Direct Group Owner is based on Socket server running on the Group Owner and clients connected to that server.
Once WiFi Direct group is formed(you can know that by checking "onConnectionInfoAvailable(WifiP2pInfo wifiP2pInfo)"), check if the current device is the Group Owner and if so, start the sockets server (similar to your code):
mServerSocket = new ServerSocket(mPort);
Log.e(getClass().getSimpleName(), "Running on port: " + mServerSocket.getLocalPort());
Then next, add this line to accept connections and store a reference of the client socket:
Socket mSocket = mServerSocket.accept();
Now, you have a reference of the client socket, you can use it to send data / messages to it. Next, the other device (client) should initiate a connection to the socket server:
mSocket = new Socket();
mSocket.bind(null);
mSocket.connect(new InetSocketAddress(mAddress, mPort), 500);
To send message from server to client:
DataOutputStream mDataOutputStream = new DataOutputStream(mSocket.getOutputStream());
Send simple message:
mDataOutputStream.writeUTF(message);
mDataOutputStream.flush();
Hope this helps.

Android WiFi Direct Data Communication Example

Can anyone suggest a good example for get an idea about creating TCP server and client with android WiFi direct to transfer data. (Actually transfering of strings not files)
Actually I did one, but I cannot get the IP of server from client side.
If server and client are connected to the same wifi network, then please try use the 192.168.1.40 IP in the client to send data to server.
For example in client:
Socket socket = new Socket("192.168.1.40", port);
Hope it helps.
package com.example.androidclient;
MyClientTask(String addr, int port){
dstAddress = addr;
dstPort = port;
}
try {
socket = new Socket(dstAddress, dstPort);
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
}

android UDP connection, not receiving any data

Im a newbie in this so please escuse me if i ask dumb questions.
Im trying to make a UDP connection between Eclipse's PC Emulator & a android phone
(or between two android phone devices).
I have a router and the phone connects to the internet thru router's wifi network. The PC is on same network also (direct cable router-PC connection). Im trying to send some text data from Server thread to Client thread but nothing is received/sent. :(
The Server java class (RE-EDITED, Server receives msg. from Client):
public class server implements Runnable
{
// the Server's Port
public static final int SERVERPORT = 6000;
// running Server thread.
public void run()
{
Log.d("redwing","server thread started.");
DatagramSocket serverSocket = null;
try
{
// Open Server Port
serverSocket = new DatagramSocket(server.SERVERPORT);
byte[] receiveData = new byte[32];
byte[] sendData = new byte[32];
// loop until "server_finished" becomes False.
while(createserver.server_finished)
{
if(renderer.gGL!=null) // ignore me, just a null pointer checker
{
// waiting for the incoming client's message packet
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
renderer.recv = new String(receivePacket.getData());
Log.d("server","packet received from client, ETA " + timing.getNow() + " " + renderer.recv); // timing getNow - just returns current system minute & second.
// server is replying to the client back with a message.
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
sendData = new String("server msg").getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
renderer.sent = new String(sendData, 0, sendData.length);
Log.d("server","packet sent to client, ETA " + timing.getNow() + " " + renderer.sent); // timing getNow - just returns current system minute & second.
}
}
// close the socket
if(serverSocket!=null) serverSocket.close();
serverSocket = null;
}
catch (Exception e)
{
Log.e("server", "Error", e);
if(serverSocket!=null) serverSocket.close();
serverSocket = null;
}
finally
{
if(serverSocket!=null) serverSocket.close();
serverSocket = null;
}
Log.d("redwing","server thread terminated.");
}
}
and the Client java class (RE-EDITED, Client does not receive msg from Server) :
public class client implements Runnable
{
public static final int CLIENTPORT = 5000;
// running Client thread.
public void run()
{
Log.d("redwing","client thread started.");
DatagramSocket clientSocket = null;
try
{
// getting local address
clientSocket = new DatagramSocket(server.SERVERPORT);
InetAddress IPAddress = InetAddress.getByName("192.168.0.100");
// displaying IP & hostname.
Log.d("client", "IP: " + IPAddress.getHostAddress() + " Name: " + IPAddress.getHostName());
byte[] sendData = new byte[32];
byte[] receiveData = new byte[32];
// Loop until client_finished becomes False.
while(createclient.client_finished)
{
if(renderer.gGL!=null) // ignore me, just a null pointer checker
{
// sending a message to the server
sendData = timing.getNow().getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, client.CLIENTPORT);
clientSocket.send(sendPacket);
renderer.sent = new String(sendData,0,sendData.length);;
Log.d("client","packet sent to server, ETA " + timing.getNow());
// waiting for the server packet message.
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
renderer.recv = new String(receivePacket.getData());
Log.d("client","packet received from server, ETA " + timing.getNow());
}
}
// close the socket
if(clientSocket!=null) clientSocket.close();
clientSocket = null;
}
catch (Exception e)
{
Log.e("client", "Error", e);
if(clientSocket!=null) clientSocket.close();
clientSocket = null;
}
finally
{
if(clientSocket!=null) clientSocket.close();
clientSocket = null;
}
Log.d("redwing","client thread terminated.");
}
}
the Permisions are enabled in the manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<user-permission android:name="android.permission.NETWORK" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
I'm running the Server on the android PC Emulator, and the Client on my android Phone.
Both Client & Server threads run just fine but ... the problem is that i dont get any data exchanged between them. The client doesn't receive anyting and the server doesnt receive anything. The packets are sent but nothing received .
What im doing wrong ?
Please help me.
Thank you in advance.
After running your emulator, type it in command prompt - "telnet localhost ", then type "redir add udp:5000:6000". Connect client with port number 5000 and open udp server with port number 6000. Then you can receive client message from udp server.
Take a look for details
clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("<pc ip>"); // instead of "localhost"
public static final String SERVERIP = "127.0.0.1"; // 'Within' the emulator!
public static final int SERVERPORT = 6000;
/* Retrieve the ServerName */
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
DatagramSocket socket = new DatagramSocket(SERVERPORT, serverAddr);

Android, problems with SocketAddress and sockets. Reverse lookup?

i have a problem with Android. I am trying to connect to a server with a proxy with no luck.
I have this code that works fine on normal Java. It only defines a proxy server and creates a socket that would connect to google with that proxy. It sends a simple GET request and then shows the response.
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.net.SocketAddress;
public class Main {
public static void main(String[] args) {
try{
//create the proxy info
SocketAddress socketAddress = new InetSocketAddress("78.137.18.67" , 8364);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, socketAddress);
// create the socket with the proxy
Socket socket = new Socket(proxy);
// connect to some address and send/receive data
socket.connect(new InetSocketAddress("www.google.com", 80));
socket.getOutputStream().write("GET /index.html HTTP/1.1\r\nHost: www.google.com\r\n\r\n".getBytes("UTF-8"));
byte result[] = new byte[1024];
socket.getInputStream().read(result);
socket.close();
System.out.println(new String(result));
}catch(Exception e){
e.printStackTrace();
}
}
}
The problem with android, with a code similar like that, is that the InetSocketAddress is doing something strange. It seems that it does a reverse lookup of the given ip, and then the socket created with the proxy tries to connect with the resolved host name, in this case is 78-137-18-67.dynamic-pool.mclaut.net.
This would not be a problem (except on performance) if the socket could resolve the hostname back to the ip address. The fact is that this hostname cannot be resolved to ip address with my internet connection (i don't know if others can do). So the reverse lookup is working fine but the normal lookups fails, so when the socket tries to connect through the proxy it raises the following exception:
08-25 19:26:46.332: ERROR/Microlog(3526): 40274 SocketConnection
[ERROR] Error establishing connection java.net.SocketException: SOCKS
connection failed: java.net.UnknownHostException:
78-137-18-67.dynamic-pool.mclaut.net
So the question is, why it is trying to connect with the hostname if i gave the ip address? Is there any way to avoid this lookup? I have tried with createUnresolved of InetSocketAddress but in this case the socket hangs on connection.
Is not a waste of time, internet connection, etc, to do a reverse DNS lookup to get the hostname (if any), and later when the socket needs to connect, resolve again the host to an ip address?
NOTE: this code is an example, the real app do not perform any http request in this way. It uses binary data packets.
To prevent a reverse lookup, you can create the InetAddress with getByAddress(byte[]).
Then pass the InetAddress instance into the InetSocketAddress constructor.
Alternatively, use the factory method InetSocketAddress.createUnresolved(String,int)
Yes it seems that the particular constructor of InetSocketAddress does a reverse DNS lookup: http://mailinglists.945824.n3.nabble.com/Android-and-reverse-DNS-lookup-issues-td3011461.html
Also, it seems that this does not happen anymore on Android 2.3.4.
In android you have to do everything with background process so that you do not write code for socket in onCreate method directly you have to do this in background so that your ui does not hangs
something like this
new Thread(new Runnable() {
#Override
public void run() {
try {
client = new Socket(ipaddress, port);
printwriter = new PrintWriter(client.getOutputStream(), true);
InputStream is = client.getInputStream();
printwriter.write(msg);
printwriter.flush();
byte[] buffer = new byte[2046];
int read;
while ((read = is.read(buffer)) != -1) {
final String output = new String(buffer, 0, read);
);
printwriter.close();
}
});
}
Log.e("message", "message send");
} catch (UnknownHostException e2) {
e2.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
Log.d("Time out", "Time");
}

Categories

Resources