Android TCP Client in phone has problems in communicating with external server - android

I have a TCP Client in Android (Java program in Eclipse). The server was another Java app running in Eclipse. Everything works fine in this situation.
When I tried to receive message from my colleague's app (developed in Rhapsody and I think C++), I receive the message only after his app is closed and not while his app is running and sending messages. Do you have any idea why this happens?
Thank you for the time and effort on this.
Cheers,
Madhu
The java server is like this:
public class TCPSendServer implements Runnable{
public static final String SERVERIP = "192.168.178.24";
public static final int SERVERPORT = 1200;
//static Category cat = Category.getInstance(TCPSendServer.class.getName());
//cat.debug("Start of main()");
public void run() {
try {
System.out.println("S: Connecting...");
ServerSocket serverSocket = new ServerSocket(SERVERPORT);
String msg = "<MSG><N>shiftDirection</N><V>1</V></MSG>";
String msg1 = "<MSG><N>vehicleSpeed</N><V>120</V></MSG>";
String msg2 = "SD<!N><V>0<!V><!MSG>";
//while (true) {
Socket client = serverSocket.accept();
try {
System.out.println("S: Sending: '" + msg + "'");
PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(client.getOutputStream())),true);
Thread.sleep (5000);
out.println(msg);
Thread.sleep (5000);
//out.println(msg2);
Thread.sleep (5000);
out.println(msg1);
//out.flush();
System.out.println("S: Sent.");
System.out.println("S: Done.");
} catch(Exception e) {
System.out.println("S: Error");
e.printStackTrace();
} //finally {
// client.close();
//}
//}
} catch (Exception e) {
System.out.println("S: First try error");
e.printStackTrace();
}
}
public static void main (String a[]) {
Thread desktopServerThread = new Thread(new TCPSendServer());
desktopServerThread.start();
}
}
The Android client code:
Main activity:
public class TCPListen extends Activity implements TCPListener {
private TextView mTitle;
public String data[] = new String[2];
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
// Set up the window layout
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.main);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
// Set up the custom title
mTitle = (TextView) findViewById(R.id.title_left_text);
mTitle.setText(R.string.app_name);
mTitle = (TextView) findViewById(R.id.title_right_text);
//TcpServiceHandler handler=new TcpServiceHandler(this);
//handler.execute("192.168.178.24");
TcpServiceHandler handler = new TcpServiceHandler(this,this);
Thread th = new Thread(handler);
th.start();
}
public String[] callCompleted(String source){
Log.d("TCP", "Std parser " + source);
mTitle.setText(source);
//String data[] = new String[2];
//if (source.matches("<MSG><N>.*</N><V>.*</V></MSG>")) {
Document doc = null;
try{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
doc = (Document) db.parse(new ByteArrayInputStream(source.getBytes()));
NodeList n = doc.getElementsByTagName("N");
Node nd = n.item(0);
String msgName = nd.getFirstChild().getNodeValue();
NodeList n1 = doc.getElementsByTagName("V");
Node nd1 = n1.item(0);
String tmpVal = nd1.getFirstChild().getNodeValue();
data[0] = msgName;
data[1] = tmpVal;
Log.d("TCP", "Inside Std parser " + data[0] + " " + data[1]);
//actionOnData(data[0], data[1]);
}
catch(Exception e){
e.printStackTrace();
}
Log.d("TCP", "Just outside Std parser " + data[0] + " " + data[1]);
return data;
//} else Log.d("TCP", "Message in wrong format " + source);
//mTitle.setText("Message in wrong format " + source);
//return data;
}
Interface:
public interface TCPListener {
public String[] callCompleted(String msg);
}
TCPServiceHandler:
public class TcpServiceHandler implements Runnable {
TCPListener _listener;
private Activity _act;
public TcpServiceHandler(TCPListener listener, Activity act){
_listener = listener;
_act = act;
}
public synchronized void run() {
// TODO Auto-generated method stub
//if(socket==null){
try {
InetAddress serverAddr = InetAddress.getByName("192.168.178.25");
Socket socket = new Socket(serverAddr, 1200);
//
while(true){
try {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
final String str = in.readLine();
this._act.runOnUiThread(new Runnable(){
public void run() {
_listener.callCompleted(str);
}
});
}
catch(Exception e){
e.printStackTrace();
}
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

This is problem with the SERVERIP here. Are you running your app from an emulator in your local machine? Your emulator is not part of your LAN. Emulator runs behind a virtual router/firewall service that isolates it from your development machine's network interfaces and settings and from the internet.
So you need to use network redirections or port forwarding to achieve communication with the server which is on a separate machine.
If you are running the app on a device then you can make that device as part of your network and then it should work.

There has been a solution, at least for the time being. I use readLine() to read contents of sockets and this expects \n or \r or similar characters until it returns the contents. This was not the issue for me when both server and client were in Java. But when the client had to receive messages from a different app, I faced this problem. It was overcome by just adding \n to the end of message sent by the other app.

Related

Can't get python server data from android client

I want to write a simple android app that sends text to python server and then puts its answer (in our case: how many vowels in the data) and use Logcat to see it really got the data.
Everything works just fine excepts for the part where the clients waits for the server response.
It just getting stuck there even though the server says it sent the data back to the client.
Does anyone have an idea what might have caused this problem?
UPDATE:
After sniffing with Wireshark I saw that the data the client and server sends to each other is "Malformed packet". Anyone knows why?
my client code:
public class MainActivity extends Activity {
private Socket socket;
private static final int SERVERPORT = 5000;
private static final String SERVER_IP = "10.0.0.1";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new ClientThread()).start();
}
public void onClick(View view) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(str);
Log.i("Tag","sent " + str);
BufferedReader input = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
try {
String read = input.readLine();
Log.i("Tag","got " + read);
} catch (IOException e) {
e.printStackTrace();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
my server code:
import socket
srv_sock = socket.socket()
ip = "0.0.0.0" # means local
port = 3001 # 0 means get random free port
srv_sock.bind((ip, port))
srv_sock.listen(5)
while True:
(new_sock, address) = srv_sock.accept()
print "Hello! this is a vowels server! You need to send a word or a
sentence and I'll give you the number of vowels in it!"
while True:
data = new_sock.recv(1024)
if data == "" :
print "Client Disconnected"
break
print "Received<<< " + data
data = data.upper()
to_send = "Num of vowels is "
cnt=0
if data.isdigit():
to_send = "ERROR:Number doesn't have any vowels!"
else:
for letter in data:
if (letter == 'A' or letter == 'E' or letter == 'O' or letter
== 'U' or letter == 'I'):
cnt += 1
to_send += str(cnt)
new_sock.send(unicode(to_send + "\n"))
print "Sent >>>" + to_send
new_sock.close()
srv_sock.close()

Android 6.0 cant create socket

I cant create a simple TCP connection to my server.
I created a AsyncTask to send messages, but it didn't work.
I added INTERNET and ACCESS_NETWORK_STATE to the permissions.
I don't know what else to try.
public class ServerCommunicator extends AsyncTask<String,Void,Void>{
public static String SERVER_IP = "192.168.2.148";
public static int SERVER_PORT = 1337;
public static String SERVER_PW = "adsfadsf";
public Context context;
#Override
protected Void doInBackground(String... params) {
//Create Command
CommandFactory cmdFactory = new CommandFactory();
Command cmd = cmdFactory.createCommand();
System.out.println("Cmd created..");
//-----
try {
System.out.println(SERVER_IP);
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
System.out.println("Created serverAddr "+ SERVER_IP);
Socket socket = new Socket(serverAddr,SERVER_PORT);
System.out.println("Socket created..");
//sends the message to the server
PrintWriter mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
String msg2Send = Crypter.Encrypt(cmd.toString(), SERVER_PW);
sendMsgAsByteArr(socket, msg2Send);
Command recCmd = cmdFactory.extractCommandFromStr(receiveMsg(socket));
socket.close();
Toast.makeText(context, recCmd.id, Toast.LENGTH_LONG).show();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private static void sendMsgAsByteArr(Socket socket, String msg) {
try {
socket.getOutputStream().write(msg.getBytes());
System.out.println("sent cmd..");
} catch (IOException e) {
e.printStackTrace();
}
}
private static String receiveMsg(Socket socket) {
String msg = "";
int c;
ArrayList<Byte> incoming = new ArrayList<Byte>();
try {
while((c = socket.getInputStream().read())!=-1) {
incoming.add((byte)c);
}
byte[] allBytes = new byte[incoming.size()];
for(int i = 0; i < incoming.size(); i++) {
allBytes[i] = incoming.get(i);
}
msg = new String(allBytes);
} catch (IOException e) {
e.printStackTrace();
}
return msg;
}
}
My program runs till Socket socket = new Socket(serverAddr, SERVER_PORT); then it stops. It doesn't show any stack trace or errors.
Any ideas?
I debugged your code, and while there were multiple issues, none were related to Android 6.
I created a simplified version of your code and got it working.
One issue is that your context reference was null, so I set it in the constructor.
Another issue is that you were trying to show a Toast on a background thread, which won't work.
Another issue was your send and receive methods, they didn't work for me.
Here's the simplified code that I got working with a TCP/IP server, tested on both Android 4.4.4 and Android 6.
You can take this and expand on it as needed:
public class ServerCommunicator extends AsyncTask<String,Void,String> {
public static String SERVER_IP = "11.222.33.444";
public static int SERVER_PORT = 1234;
public Context context;
public ServerCommunicator(Context c) {
this.context = c;
}
#Override
protected String doInBackground(String... params) {
try {
System.out.println(SERVER_IP);
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
System.out.println("Created serverAddr "+ SERVER_IP);
Socket socket = new Socket(serverAddr,SERVER_PORT);
System.out.println("Socket created..");
//sends the message to the server
PrintWriter mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
String msg2Send = "{\"HelloWorld\", \"1234\"}";
mBufferOut.println(msg2Send);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String result = in.readLine();
System.out.println("result: " + result);
socket.close();
return result;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
Toast.makeText(context, result, Toast.LENGTH_LONG).show();
}
}
}

How to create server to use chat room realtime (SignalR) in android

I am beginner in android xamarin. I want to use chat room realtime using SignalR. But i dont know what is "http://10.0.2.2:8081/echo" mean in this example. Is it a server???There are something in that server - like php file, database or something else???
hope your answer, thanks :D or anybody show me how to build a group chat application, please(use socket like :http://www.androidhive.info/2014/10/android-building-group-chat-app-using-sockets-part-1/ or SignalR in xamarin )
using System.Collections.Generic;
using Android.App;
using Android.OS;
using Android.Widget;
namespace SignalR.Client.MonoDroid.Sample
{
[Activity(Label = "SignalR.Client.MonoDroid.Sample", MainLauncher = true, Icon = "#drawable/icon")]
public class DemoActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
var messageListAdapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, new List<string>());
var messageList = FindViewById<ListView>(Resource.Id.Messages);
messageList.Adapter = messageListAdapter;
var connection = new Connection("http://10.0.2.2:8081/echo");
connection.Received += data =>
RunOnUiThread(() => messageListAdapter.Add(data));
var sendMessage = FindViewById<Button>(Resource.Id.SendMessage);
var message = FindViewById<TextView>(Resource.Id.Message);
sendMessage.Click += delegate
{
if (!string.IsNullOrWhiteSpace(message.Text) && connection.State == ConnectionState.Connected)
{
connection.Send("Android: " + message.Text);
RunOnUiThread(() => message.Text = "");
}
};
connection.Start().ContinueWith(task => connection.Send("Android: connected"));
}
}
}
10.0.x.x is a private subnet (http://en.wikipedia.org/wiki/Private_network). In this example then it is talking about you running some kind of server system on your computer on port 8081.
http://10.0.2.2:8081/echo
10.0.2.2 is the ip of your server
8081 is the port on which server listening your request and give response on same port
echo is the automated generate respone which is given to you on every request with same request(String)
public static class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
String s;
String red;
String loc;
public MyClientTask(String addr, int port,String msg){
dstAddress = addr;
dstPort = port;
loc=msg;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
DataOutputStream dataOutputStream = null;
ObjectInputStream inputStream=null;
try {
SocketAddress socketAddress = new InetSocketAddress(dstAddress,dstPort);
socket = new Socket();
socket.setTcpNoDelay(true);
socket.setSoTimeout(5000);
socket.connect(socketAddress, 50000);
// socket = new Socket(dstAddress, dstPort);
System.setProperty("http.keepAlive", "false");
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.writeUTF(loc);
///inputStream = new ObjectInputStream(socket.getInputStream());
InputStream is = socket.getInputStream();
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
BufferedReader br = new BufferedReader(
new InputStreamReader(is));
out.println("");
//response = br.readLine();
try{
while((s=br.readLine())!=null){
red=red+s;
Log.i("server", ""+red);
}
Log.i("server", ""+red);
}catch(Exception ex){
ex.printStackTrace();
}
Log.i("Server response ", "hi"+s);
try {
System.out.println("Read back from server: " + response);
}
catch(Exception e) {
Log.i("Server response ", response+e);
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
}finally{
if(socket != null){
try {
dataOutputStream.flush();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
res=response;
Log.i("response:", "res"+res);
// Toast.makeText(getApplicationContext(), "hi"+res, Toast.LENGTH_LONG).show();
super.onPostExecute(result);
}
}
call this method to send request and get response on your desired place
public void sendtoserver(String msg){
if(isConnectingToInternet()){
servermsg="$loc"+","+ieminumber+","+formattedDate2+","+formattedDate1+","+formattedDate2+","+formattedDate1+","+1+","+lat1+","+"N"+","+lon1+"*";
//10.0.2.2:8081/echo
MyClientTask myClientTask = new MyClientTask(
"10.0.2.2",8081,msg);
myClientTask.execute();
}
}
If you run your app on an emulator and your server runs on the same pc as the emulator then the only way your client app can reach that server is using ip 10.0.2.2 as Google implemented it that way. Meanwhile your computer can have local ip like 192.168.1.12 but your app can not use that. Also the server on the pc is reachable as localhost or 127.0.0.1 by clients running on the same pc. Your app does not run on that pc. Your app runs on the emulator.

how to send message to all connected client from server

i've created an android application in which, android application act as the client, and server resides in the desktop application.
suppose there are 10 android application runs the same at a time on 10 different android tablets, when one updation received from one tablet, the desktop application sends the updation to all other remaining tablets. how could the server knows how many clients are connected and how to send the message to all the clients
what i plan is to run a server in all android so that when one updation received from one tablet, the desktop application sends the updation to all other remaining tablets.
can anyone please tell me some suggestion regarding this.
Client side
private int SERVER_PORT = 9999;
class Client implements Runnable {
private Socket client;
private PrintWriter out;
private Scanner in;
#Override
public void run() {
try {
client = new Socket("localhost", SERVER_PORT);
Log.d("Client", "Connected to server at port " + SERVER_PORT);
out = new PrintWriter(client.getOutputStream());
in = new Scanner(client.getInputStream());
String line;
while ((line = in.nextLine()) != null) {
Log.d("Client", "Server says: " + line);
if (line.equals("Hello client")) {
out.println("Reply");
out.flush();
}
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Server class
class ServerThread implements Runnable {
private ServerSocket server;
#Override
public void run() {
try {
server = new ServerSocket(SERVER_PORT);
Log.d("Server", "Start the server at port " + SERVER_PORT
+ " and waiting for clients...");
while (true) {
Socket socket = server.accept();
Log.d("Server",
"Accept socket connection: "
+ socket.getLocalAddress());
new Thread(new ClientHandler(socket)).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ClientHandler implements Runnable {
private Socket clientSocket;
private PrintWriter out;
private Scanner in;
public ClientHandler(Socket clietSocket) {
this.clientSocket = clietSocket;
}
#Override
public void run() {
try {
out = new PrintWriter(clientSocket.getOutputStream());
in = new Scanner(clientSocket.getInputStream());
String line;
Log.d("ClientHandlerThread", "Start communication with : "
+ clientSocket.getLocalAddress());
out.println("Hello client");
out.flush();
while ((line = in.nextLine()) != null) {
Log.d("ClientHandlerThread", "Client says: " + line);
if (line.equals("Reply")){
out.print("Server replies");
out.flush();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
You could save the Sockets in a List and send a message through all the OutputStreams in that List:
Socket socket = Server.accept();
sockets.add(socket); //sockets is an ArrayList<Socket>
public void sendMessageToEveryone(String msg) {
for(Socket s : sockets) {
s.getOutputStream().write(msg.getBytes());
s.getOutputStream().flush();
}
You could use the Google Cloud Messaging service.
Take a look at this page:
https://developer.android.com/google/gcm/index.html

how to update interface to MainActivity from thread activity in different class?

now i'm making socket connection to connect multiple client to one server. everything fine, i make thread in different class. But when i will fill textView with string from thread activity, i can't. please help
this MainActivity:
public class MainActivity extends Activity {
private static int port = 6000;
TextView txt;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt = (TextView) findViewById(R.id.txtCommand);
txt.setText("Server : ");
ServerSocket server1 = null;
Server gameServer = new Server();
try {
server1 = new ServerSocket(port);
// .. server setting should be done here
} catch (IOException e) {
System.out.println("Could not start server!");
// return ;
}
while (true) {
Socket client = null;
try {
client = server1.accept();
gameServer.handleConnection(client);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Server {
private ExecutorService executor = Executors.newCachedThreadPool();
public void handleConnection(Socket client) throws IOException {
PlayerConnection newPlayer = new PlayerConnection(this, client);
txt.setText(newPlayer.getuname());
this.executor.execute(newPlayer);
}
// add methods to handle requests from PlayerConnection
}
and this thread adctivity :
public class PlayerConnection implements Runnable {
private Server parent;
private Socket socket;
private PrintWriter out;
private BufferedReader in;
String line;
protected PlayerConnection(Server parent, Socket socket) throws IOException {
this.parent = parent;
this.socket = socket;
this.in = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
this.out = new PrintWriter(new OutputStreamWriter(
socket.getOutputStream()));
}
public void run() {
while(!this.socket.isClosed()) {
try {
//int nextEvent = this.in.readInt();
line = in.readLine();
System.out.println("Server Receive : "
+ line);
out.println("Server Sent :" +line);
System.out.println("SEND : "
+ line);
out.flush();
if (line == null){
this.socket.isClosed();
break;
}
} catch (IOException e) {}
}
I realized that you have a while loop that never ends in your onCreate method. try to move that loop in to your thread. this loop blocks inputs of your application.
while (true) {
Socket client = null;
try {
client = server1.accept();
gameServer.handleConnection(client);
} catch (IOException e) {
e.printStackTrace();
}
you can use handler or runOnUiThread method.

Categories

Resources