[Q] Connecting phones via UDP - Android Software Development

Code:
I am in a networking course and was assigned a project that we can complete in any language or environment. Being the Android lover that I am I naturally wanted to do this on my phone. The part I am having an issue with should be simple and I am starting to think I can not establish a connection using UDP between the phones. What I am trying to do is use one phone as a server and one as a client. The client sends a message to the server and the server changes the string to upper case. (this is not the project, but a good step to see if it is working.) Does anyone know why the server and client would not be connecting or if it is even possible?
This is the server, below is the client, main launch screen, and main.xml
Code:
package com.csc.networking;
import java.net.*;
import android.util.Log;
public class UDPServer
{
public void main() throws Exception
{
Log.d("s","1");
DatagramSocket serverSocket = new DatagramSocket(6699);//create a datagram socket at the specified port number
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
Log.d("s","2");
while(true)
{
Log.d("s","3");
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
//To Do: construct a DatagramPacket object called receivePacket. Use the constructor of the class DatagramPacket
//that takes two parameters: 1. the array of bytes (receiveData) and 2. the length of that array.
Log.d("s","3.5");
//To Do: use the method receive on the DatagramSocket object to receive the packet sent from the client.
//the method receive takes one parameter (the DatagramPacket object constructed in the above step).
serverSocket.receive(receivePacket);
Log.d("s","again");
Log.d("s","3.75");
String sentence = new String(receivePacket.getData());//extract the String from the array of bytes.
Log.d("s",sentence);
Log.d("s","4");
InetAddress IPAddress = receivePacket.getAddress();//extract the IP address of the client
int port = receivePacket.getPort();//extract the port number from the packet
String capitalizedSentence = sentence.toUpperCase();//change the sentence received by the server
sendData = capitalizedSentence.getBytes();//convert it to an array of bytes
Log.d("s","5");
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
//To Do: construct a DatagramPacket object called sendPacket. Use the constructor of the class DatagramPacket
//that takes 4 parameters: 1. the array of bytes to be sent. 2. the length of that array of bytes.
//3. the IP address of the client (use the object IPAddress) and 4. the port number of the process running in
//the client.
//To Do: send the packet to the client using the method send on the DatagramSocket object. The metho send
//takes one parameter which is the packet constructed in the above step.
Log.d("s","5.5");
serverSocket.send(sendPacket );
Log.d("s","6");
}
}
}
Client:
Code:
package com.csc.networking;
import java.io.*;
import java.net.*;
import android.util.Log;
import android.widget.*;
public class UDPClient {
public void main(String string) throws Exception
{
Log.d("help", "1");
//EditText connectAddress = (EditText)findViewById(R.id.connectAddress);
Log.d("help", "2");
String hostIP = "10.60.5.79"; //connectAddress.getText().toString();
Log.d("help", "3");
String coded = string;
Log.d("help", "4");
DatagramSocket clientSocket = new DatagramSocket();//this line creates a datagram socket, this does not
//create a TCP connection with the server, note how we do not have server and process info as parameters to
//the constructor
Log.d("help", "5");
InetAddress IPAddress = InetAddress.getByName(hostIP); //this line invokes DNS to lookup the IP address
//of the hostname. If IP address is provided, it stores it in the object IPAddress.
Log.d("help", "6");
byte[] sendData = new byte[1024]; //array of bytes to be sent to server
Log.d("help", "7");
byte[] receiveData = new byte[1024]; //array of bytes that client will receive from server
Log.d("help", "8");
sendData = coded.getBytes(); //this converts sentence to an array of bytes and stores it in sendData.
Log.d("help", "9");
DatagramPacket sendPacket = new DatagramPacket(sendData,sendData.length,IPAddress,6699);
//To DO: construct a DatagramPacket object called sendPacket. The constructor of the DatagramPacket class
//takes the following parameters: 1. the array of bytes to be sent. 2. the length of the array of bytes.
//3. the IPAddress of the destination (use the object IPAddress) and 4. the port number of the process running
//at the destination.
Log.d("help", "10");
clientSocket.send(sendPacket);
//To DO: call the method send on the DatagramSocket object to send the datagram packet. The method send takes
//the DatagramPacket object as a prameter and sends it through the socket.
Log.d("help", "11");
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
//To Do: construct a new DatagramPacket object called recievePacket. This is the packet that the client will
//receive from the destination. Use the constructor that takes two parameters: 1. an array of bytes (receiveData) and
//2. the length of that array.
Log.d("help", "12");
clientSocket.receive(receivePacket);
//To Do: use the method receive on the DatagramSocket object to receive the datagram packet from the server.
//The method receive takes a parameter which is the DatagramPacket constructed in the above step.
Log.d("help", "13");
String modifiedSentence = new String(receivePacket.getData());//this converts an array of bytes to a string.
Log.d("help", "14");
TextView decoded = (TextView)findViewById(R.id.decoded);
Log.d("help", "15");
decoded.setText(modifiedSentence);
Log.d("help", "16");
clientSocket.close();//this closes the connection.
Log.d("help", "17");
}
private EditText findViewById(int connectaddress) {
// TODO Auto-generated method stub
return null;
}
}
Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:baselineAligned="true" android:orientation="vertical"
android:layout_width="wrap_content" android:layout_height="fill_parent">
<TextView android:text="@string/Title" android:id="@+id/Title"
android:layout_width="fill_parent" android:gravity="center"
android:textSize="24px" android:layout_height="wrap_content" />
<EditText android:id="@+id/editText1" android:layout_below="@+id/Title"
android:layout_alignLeft="@+id/Title" android:layout_alignRight="@+id/Title"
android:layout_width="fill_parent"
android:layout_height="wrap_content" android:scrollbarAlwaysDrawVerticalTrack="true" android:scrollbars="vertical" android:singleLine="true" android:hint="@string/Hint"/>
<RelativeLayout android:layout_width="wrap_content"
android:layout_below="@+id/editText1" android:id="@+id/relativeLayout1"
android:layout_height="wrap_content" android:layout_alignLeft="@+id/editText1"
android:layout_alignRight="@+id/editText1">
<Button android:layout_width="wrap_content"
android:layout_below="@+id/startServer" android:layout_height="wrap_content"
android:layout_alignLeft="@+id/startServer"
android:layout_alignRight="@+id/startServer" android:id="@+id/Send"
android:text="@string/Send" />
<EditText android:layout_width="wrap_content" android:layout_below="@+id/Send" android:layout_height="wrap_content" android:layout_alignLeft="@+id/Send" android:layout_alignRight="@+id/Send" android:id="@+id/connectAddress" android:hint="Enter Ip Address Here"></EditText>
<TextView android:text="Decoded" android:layout_width="wrap_content" android:layout_below="@+id/connectAddress" android:id="@+id/decoded" android:layout_height="wrap_content" android:layout_alignLeft="@+id/connectAddress" android:layout_alignRight="@+id/connectAddress"></TextView>
<Button android:layout_width="fill_parent" android:id="@+id/startServer" android:text="@string/Start " android:layout_height="wrap_content" android:layout_alignParentRight="true"></Button>
</RelativeLayout>
</RelativeLayout>
Code:
package com.csc.networking;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class launchScreen extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button SendButton = (Button)findViewById(R.id.Send);
SendButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
Log.d("click", "1");
EditText codedMessage = (EditText)findViewById(R.id.editText1);
UDPClient client = new UDPClient();
String msg = codedMessage.getText().toString();
Log.d("click", msg);
Log.d("click", "2");
client.main(msg);
Log.d("click", "3");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Button ServerButton = (Button)findViewById(R.id.startServer);
ServerButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
UDPServer server = new UDPServer();
server.main();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}

Since your phones actual network is a private network, there's no way to run a server on the phone. Its ports simply won't be available to the outside world. You need some kind of server that is visible to the internet (not firewalled) to marshal the connection between the two phones that are not visible to the internet.

Gene Poole said:
Since your phones actual network is a private network, there's no way to run a server on the phone. Its ports simply won't be available to the outside world. You need some kind of server that is visible to the internet (not firewalled) to marshal the connection between the two phones that are not visible to the internet.
Click to expand...
Click to collapse
Does that mean phone to phone will not work, but phone to stand alone java app will?

What do you mean by stand-alone java app? Phone to self (One app talks UDP to another app on the same phone)?

Phone- computer. Having the server on the computer and the client on the phone.

It is quite possible that the routers on your network don't permit routing packed from one "inside" address to another -- That would mean that you could route packets (through NAT) to the outside world and back again, but not phone-to-phone.
For security reasons, I'd be pretty disappointed to find out that one could route phone-to-phone.

Related

Passing string variable to dll -> NotSupportedException

This is all very frustrating! I have an "ez_tapi.dll" from Paul Vangelderp and it works a treat for eVB but I can not seem to use it in C#.
If anybody feel inspired they can test this themselves: the zipped attachment contains Paul's DLL code (C++ project) and his small test project (eVB), which proves that the DLL works well. Also included is my micky-mouse C# test project: I can dial up a modem and establish a GSM/V.110 connection, but when I try to send data by calling Ez_tapi_UTransmit() the application blows. I am assuming we have a problem passing the string between managed and unmanaged code.
I have buggered about with every imaginable combination of ref and out (the C# equivalent of ByVal and ByRef) for both Unicode and with byte/char arrays - all I ever get is the totally unhelpful "NotSupportedException". Is this a marshaling issue and if so how can I fix it?
Any help would be most welcome - I think Paul is planning on offering his DLL as a general purpose encapsulation of TAPI for application programmers who only need to quickly make a dial-up data connection for their PocketPC projects... once we have got it working!
Best regards,
Peter Beedell.
Re:
You can wrap library in this method:
//Function to Dial up a telephone number and get a Comm Handle
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_UDial")]
private static extern int TAPIUDial(string szPhoneNumber);
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_Dial")]
private static extern int TAPIDial(string szPhoneNumber);
//Function to Return the Current Tapi Status
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_Status")]
private static extern uint TAPIStatus();
// Function to Return the TAPI handle
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_Handle")]
private static extern uint TapiHandle();
//Function to close line and release all handles
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_Shutdown")]
private static extern bool TapiShutDown();
//Transmit a Unicode string
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_UTransmit")]
private static extern bool TapiUTransmit(string txData, uint size);
//Transmit a Transmit a char (Byte) string
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_Transmit")]
private static extern bool TapiTransmit(string txData, uint size);
//Receive a Unicode string
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_UReceive")]
private static extern uint TapiUReceive(string rxData, uint size);
//Receive a Receive a char (byte) string
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_Receive")]
private static extern uint TapiReceive(string rxData);
// Return how many characters are waiting in the buffer
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_Rx_Count")]
private static extern uint TapiRxCount();
//Wait for a Unicode Text String with timeout value
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_UWait")]
private static extern bool TapiUWait(string What, uint length, uint Timeout);
//Wait for a char (byte) Text String with timeout value
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_Wait")]
private static extern bool TapiWait(string What, uint length, uint Timeout);
bye

C# SendMessage to Ignore/Answer calls

I am in need of some help.
I need to be able to utilize the Win32 SendMessage API (via C#) to Ignore/Answer phone calls on a whim. The current test bed is Windows Mobile 5.0, and from what I have been able to gather, the program that I should be sending the message to is cprog.exe. So the question is, should I be sending anything other than the WM_LBUTTONDOWN, WM_RBUTTONDOWN events in order to do so?
Code:
public class Message
{
public const int WM_LBUTTONDOWN = 0x0201;
public const int WM_RBUTTONDOWN = 0x0204;
}
[DllImport("coredll.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
...
Win32.SendMessage(pc.Handle, Win32.Message.WM_RBUTTONDOWN, 0, 0);
Well if you just want an app that will auto send a txt to a phone call that you can't answer, it's in the forums, Mobile Secretary. And yes, I believe from what your doing cprog.exe is the phone application.

PPC with Windows Mobile as Server

I have tried for some hours now to catch the problem, nowhere are good resources to read.
I have a server application running on my phone (Windows Mobile 6.1)
Binding the TCP Listener to 127.0.0.1ORT does work, if I type the URL from within the device.
Then I tried to connect via WIFI. At first: All WiFi Settings are correct, I know all IPs and pings are possible ... BUT: When I try to access the server from within the wifi network I don't get through. I've bound the listener for testing purposes to 127.0.0.1 and to the IP of my Wifi card. but nothing helped. Is there a kind of firewall or why can't I use a socket connection from PC to PPC?
This should work. I've create a remote-control program via TCP/IP and there were no issues.
Can you post the code for Bind / Listen?
radhoo said:
Can you post the code for Bind / Listen?
Click to expand...
Click to collapse
Code:
byte[] byteBuffer = new byte[1024];
string stringBuffer = null;
[COLOR="Red"] IPAddress localhost = IPAddress.Parse("0.0.0.0");
// I also tried 127.0.0.1 and the IP of my phone in WiFi
TcpListener httpDaemon = new TcpListener(localhost, 80);
httpDaemon.Start();
[/COLOR]
while (true)
{
TcpClient httpBrowser = httpDaemon.AcceptTcpClient();
NetworkStream commStream = httpBrowser.GetStream();
int i;
// Loop to receive all the data sent by the client.
while ((i = commStream.Read(byteBuffer, 0, byteBuffer.Length)) != 0)
{
stringBuffer = System.Text.Encoding.ASCII.GetString(byteBuffer, 0, i);
}
MessageBox.Show(stringBuffer);
httpBrowser.Close();
Provided your code is good, maybe check if the socket is actually listening, there's netstat tool in dotFred's task manager: http://www.dotfred.net/TaskMgr.htm
Furthermore, you can see if the traffic ever reaches your PPC with hSniffer:
http://winm-soft.atspace.com/
You don't seem to be checking any of the return values.
Have you done that?
You might be facing different conditions than when you bind to the loopback adapter.
theq86 said:
Code:
byte[] byteBuffer = new byte[1024];
string stringBuffer = null;
[COLOR="Red"] IPAddress localhost = IPAddress.Parse("0.0.0.0");
// I also tried 127.0.0.1 and the IP of my phone in WiFi
TcpListener httpDaemon = new TcpListener(localhost, 80);
httpDaemon.Start();
[/COLOR]
while (true)
{
TcpClient httpBrowser = httpDaemon.AcceptTcpClient();
NetworkStream commStream = httpBrowser.GetStream();
int i;
// Loop to receive all the data sent by the client.
while ((i = commStream.Read(byteBuffer, 0, byteBuffer.Length)) != 0)
{
stringBuffer = System.Text.Encoding.ASCII.GetString(byteBuffer, 0, i);
}
MessageBox.Show(stringBuffer);
httpBrowser.Close();
Click to expand...
Click to collapse
try other different port rather than http port = 80
mobile phone not design to be a web server.

Getting data from a data sms??

Hello!!
I have a problem with data sms... I get it to send the sms and the receiver can fetch it but i cant get any more info about it then the sender number...
to send the sms I use:
Code:
sms.sendDataMessage(phoneNumberTo, null, portNR, message.getBytes(), sentPI, null);
and to receive it use:
Code:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.gsm.SmsMessage;
import android.widget.Toast;
public class SMSReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
StringBuilder sb = new StringBuilder();
Bundle bundle = intent.getExtras();
Object[] pdusObj = (Object[]) bundle.get("pdus");
pdusObj[0].toString();
SmsMessage[] messages = new SmsMessage[pdusObj.length];
for (int i = 0; i < pdusObj.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
}
for (SmsMessage currentMessage : messages) {
//use the info here
String a = currentMessage.getDisplayMessageBody(); //null
String b = currentMessage.getMessageBody(); //null
String c = currentMessage.getUserData().toString(); //non understandable
String d = currentMessage.getDisplayOriginatingAddress(); //the sender number
}
}
}
so how do I get the message string from this?
sms.sendDataMessage(phoneNumberTo, null, portNR, message.getBytes(), sentPI, null);

Socket in android service

So I need to make a service that connects to a server with Socket, and when it recieves certain string, it sends a notification.
This is what i tried to make:
Code:
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
public class SmokeChecker extends Service {
[user=439709]@override[/user]
public int onStartCommand(Intent intent, int flags, int startId) throws Exception {
Socket SOCK = new Socket("localhost",444);
PrintStream PS = new PrintStream(SOCK.getOutputStream());
PS.println("Hello from client: " + Build.MANUFACTURER + " " + Build.MODEL);
InputStreamReader IR = new InputStreamReader(SOCK.getInputStream());
BufferedReader BR = new BufferedReader(IR);
String MESSAGE = BR.readLine();
if(MESSAGE.equals("s")) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentText("Fire alert, smoke detected!")
.setContentTitle("Attention!");
NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(0, builder.build()); //notification
}
if(MESSAGE.equals("g")) {
NotificationCompat.Builder builder2 = new NotificationCompat.Builder(this)
.setContentText("Fire alert, gas detected!")
.setContentTitle("Attention!");
NotificationManager manager2 = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
manager2.notify(0, builder2.build()); //notification
}
return START_STICKY;
}
[user=439709]@override[/user]
public IBinder onBind(Intent intent){
return null;
}
[user=439709]@override[/user]
public void onCreate(){
super.onCreate();
}
[user=439709]@override[/user]
public void onDestroy(){
super.onDestroy();
Toast.makeText(this, "Lost connection to server.", Toast.LENGTH_LONG).show();
}
}
Is this right way to do it? I get an error with throws Exception part.
Or should I do it in onBind method?
I'm really new to both services and networking...
Maro18 said:
So I need to make a service that connects to a server with Socket, and when it recieves certain string, it sends a notification.
This is what i tried to make:
Code:
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
public class SmokeChecker extends Service {
[user=439709]@override[/user]
public int onStartCommand(Intent intent, int flags, int startId) throws Exception {
Socket SOCK = new Socket("localhost",444);
PrintStream PS = new PrintStream(SOCK.getOutputStream());
PS.println("Hello from client: " + Build.MANUFACTURER + " " + Build.MODEL);
InputStreamReader IR = new InputStreamReader(SOCK.getInputStream());
BufferedReader BR = new BufferedReader(IR);
String MESSAGE = BR.readLine();
if(MESSAGE.equals("s")) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentText("Fire alert, smoke detected!")
.setContentTitle("Attention!");
NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(0, builder.build()); //notification
}
if(MESSAGE.equals("g")) {
NotificationCompat.Builder builder2 = new NotificationCompat.Builder(this)
.setContentText("Fire alert, gas detected!")
.setContentTitle("Attention!");
NotificationManager manager2 = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
manager2.notify(0, builder2.build()); //notification
}
return START_STICKY;
}
[user=439709]@override[/user]
public IBinder onBind(Intent intent){
return null;
}
[user=439709]@override[/user]
public void onCreate(){
super.onCreate();
}
[user=439709]@override[/user]
public void onDestroy(){
super.onDestroy();
Toast.makeText(this, "Lost connection to server.", Toast.LENGTH_LONG).show();
}
}
Is this right way to do it? I get an error with throws Exception part.
Or should I do it in onBind method?
I'm really new to both services and networking...
Click to expand...
Click to collapse
i don't know if that's the problem , but i would suggest removing "throws exception" and surround the code with try/catch ( just for testing ).
Are you trying to connect to a server , or someone else to connect to android device ? it looks like the second one, but anyway you should use the internal ip ( assuming you are on the same network ) or external ip of the server( if you are not testing in local network) and not localhost
The server just sends some data to my device and then notification should pop.
The block socket will block your code in onStartCommand. You need to create a thread in onStartCommand and write the communication code in this thread.
You need to create thread by calling
Code:
socketThread = new Thread(socketRunnable);
socketThread.start();
Where socketRunnable is
Code:
socketRunnable = new Runnable() {
public void run() {
// your socket code
}
};
As your notification operate with UI, you need to execute it on UI thread.
You can use Handler class for it.

Categories

Resources