I have a client android app and a server program on PC. In client app, I start a new thread in onCreate() of my Activity. In that thread, there is an infinite loop which sends message to the server. But there is sometimes a delay of up to 5 seconds. Here is the code of client side:
EDIT
new Thread(new Runnable() {
public void run() {
Socket socket = null;
PrintWriter out = null;
try {
socket = new Socket(ip, 1755);
out = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e) {
e.printStackTrace();
}
while(true) {
if(socket != null) {
out.println(msg);
}
}
}
}).start();
Now the message is not being delivered.
Refer this code ,
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* #author Krish
*/
public class Client {
public void connect() {
new Thread(new ClientThread()).start();
}
public void disconnect() {
try {
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void sendMessage(String msg) {
try {
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
private Socket socket;
class ClientThread implements Runnable {
private static final int SERVERPORT = 6000;
private static final String SERVER_IP = "10.0.2.15";
#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();
}
}
}
}
And also find optimization techniq
Could be because you are creating infinite amount of sockets and sending. Rather than creating once and sending then closing or could be a network issue.
Related
I have a an application which communicates between two android devices through socket. It seems like they do connect, but when data from the client socket is read by ServerSocket (using InputStream), it doesnot return the desired result (it is supposed to return somrthing like "21.24891706//95.23659845//ff8iuj67898n47fu" ).Instead I'm getting " [B#416b9488" as the message.
My client runs an AsyncTask and server runs a Thread.
Can you please help me solve this problem? Any help will is appreciated. Thanks in advance.
Here is Server.java which runs on the server:
import android.content.Context;
import android.widget.Toast;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;
public class Server {
Context context;
ServerSocket serverSocket;
String message = "";
static final int socketServerPORT = 8080;
ShowConnectedStudents activity;
public Server(ShowConnectedStudents callingActivity) {
activity = callingActivity;
Thread socketServerThread = new Thread(new SocketServerThread());
socketServerThread.start();
}
public int getPort() {
return socketServerPORT;
}
public void onDestroy() {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class SocketServerThread extends Thread {
int count = 0;
byte buffer[] = new byte[1024];
int bytesRead;
String message;
#Override
public void run() {
try {
// create ServerSocket using specified port
serverSocket=new ServerSocket();
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress(socketServerPORT));
while (true) {
// block the call until connection is created and return
// Socket object
Socket socket = serverSocket.accept();
message = "";
InputStream input = socket.getInputStream();
BufferedInputStream br= new BufferedInputStream(input);
while ((bytesRead = br.read(buffer)) != -1 ) {
message += " " + buffer.toString();
}
message += socket.isConnected();
message+=":"+socket.isClosed();
input.close();
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
activity.status.setText("Message is: " + message);
}
});
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Here is Client.java which runs on the client:
import android.os.AsyncTask;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String status = "";
double Lat,Long;
String deviceId;
Socket socket = null;
ConnectToDevice activity;
byte buffer[] = new byte[1024];
int bytesRead;
Client(String addr, int port,double latitude,double longitude,String deviceIdentification,ConnectToDevice callingActivity) {
dstAddress = addr;
dstPort = port;
Lat=latitude;
Long=longitude;
deviceId=deviceIdentification;
activity=callingActivity;
if(dstAddress.charAt(0)=='/'){
dstAddress=dstAddress.substring(1);
}
}
#Override
protected Void doInBackground(Void... arg0) {
while(socket==null){
try {
socket = new Socket(dstAddress, dstPort);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
OutputStream outputStream = socket.getOutputStream();
PrintStream printStream = new PrintStream(outputStream,true);
printStream.print(Lat + "//" + Long+"//"+deviceId);
printStream.flush();
} catch (UnknownHostException e) {
e.printStackTrace();
status = "UnknownHostException: " + e.toString();
} catch (IOException e) {
e.printStackTrace();
status = "IOException: " + e.toString();
} finally {
}
return null;
}
#Override
protected void onPostExecute(Void result) {
activity.statusText.setText(Lat+ "//" + Long+"//"+deviceId);
super.onPostExecute(result);
}
}
toString() on a byte[] is not what you want, you're getting basically the memory address of the byte array
instead convert to a string, something like this
while ((bytesRead = br.read(buffer)) != -1 ) {
message += " " + new String(buffer, 0, bytesRead);
}
I have figured out another way, before reading this accepted answer. I'm posting it in case if it benefit anyone.
My data is text-only. So I wrapped the socket's input stream inside a Scanner.
InputStream input = socket.getInputStream();
Scanner scanner= new Scanner(input);
while(scanner.hasNextLine()){
message+=scanner.nextLine();
}
I am trying to develop an app in which
1.client sends request to server for connection(IP address+PORT no.)+sends data using "PrintStream"+Tries to read the data from Server(Using Inputstream)
2.Client creates the socket.
3.Server reads the data send by Client
4.SERVER writes the data using "PrintStream" at same time point no 3.
Problem is at point 4 Data written by SERVER is not Read by "INPUTSTREAM" of client(Point 1)
I dont know these Simultaneous operation are possible or not.If possible then how.If not then what is the alternate way?
Server Code
package com.example.loneranger.ser;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;
public class MainActivity extends Activity {
TextView ip;
TextView msg;
String data = "";
ServerSocket httpServerSocket;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ip = (TextView) findViewById(R.id.infoip);
msg = (TextView) findViewById(R.id.msg);
ip.setText(getIpAddress() + ":"
+ 8080 + "\n");
Server server = new Server();
server.start();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (httpServerSocket != null) {
try {
httpServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces
.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface
.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();
if (inetAddress.isSiteLocalAddress()) {
ip += "IP: "
+ inetAddress.getHostAddress() + "\n";
}
}
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}
return ip;
}
private class Server extends Thread {
#Override
public void run() {
Socket socket = null;
try {
httpServerSocket = new ServerSocket(8888);
while(true){
socket = httpServerSocket.accept();
HttpResponseThread httpResponseThread =
new HttpResponseThread(
socket);
httpResponseThread.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class HttpResponseThread extends Thread {
Socket socket;
HttpResponseThread(Socket socket){
this.socket = socket;
}
#Override
public void run() {
BufferedReader BReader;
PrintWriter printer;
String request;
try { InputStream inputStream = socket.getInputStream();
BReader = new BufferedReader(new InputStreamReader(inputStream));
request = BReader.readLine();
Thread.sleep(500);
printer = new PrintWriter(socket.getOutputStream(), true);
printer.print("hello laundu");
printer.flush();
String ip123=socket.getInetAddress().toString();
printer.close();
BReader.close();
socket.close();
data += "Request of " + request
+ " from "+ ip123 + "\n";
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
msg.setText(data);
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return;
}
}
}
Client Code
mport android.os.AsyncTask;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
TextView textResponse;
MainActivity activity;
OutputStream outputStream;
BufferedReader BReader;
String request;
Client(String addr, int port, TextView textResponse) {
dstAddress = addr;
dstPort = port;
this.textResponse=textResponse;
this.activity=activity;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
Server server = new Server(socket);
server.start();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.print("futfujb");
out.flush();
/*
* notice: inputStream.read() will block if no data return
*/
} 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 {
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}*/
return null;
}
#Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}
private class Server extends Thread {
Socket socket;
Server(Socket socket)
{
this.socket=socket;
}
#Override
public void run() {
try { //Thread.sleep(500);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(
1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
if(inputStream.available()>0)
{
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
}
inputStream.close();
socket.close();
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
As I commented above, there is nothing in this code that corresponds to either of these steps:
2.Server gets the request creates new SOCKET connection.
(a) There is no request, and (b) the server does not create a new connection. The client creates it. The server accepts it.
3.Server reads the data send by Client.
The client doesn't send any data.
There are two problems here (at least):
The server is blocking in readLine() waiting for a message that the client never sends. So it never gets to its own send, so nothing is received by the client. Have the client send a request, as per the comments.
The client is incorrectly using available(). Remove this test and let the client fall through into the read loop. It will exit that when the peer (the server) closes the connection.
I want to create a Service that runs in the background and checks if the client sends a message to the server and answers to it.
Here's what I tried so far:
package com.server.test;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerService extends Service {
private static ServerSocket serverSocket;
private static Socket clientSocket;
private static InputStreamReader inputStreamReader;
private static BufferedReader bufferedReader;
private static String message;
Thread serverThread;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
System.out.println("hello1");
Toast.makeText(this, "Server Started", Toast.LENGTH_LONG).show();
serverThread = new Thread(new Runnable() {
public void run() {
try {
System.out.println("hello2");
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.out.println("Could not listen on port: 4444");
}
System.out.println("Server started. Listening to the port 4444");
while (true) {
System.out.println("hello3");
try {
clientSocket = serverSocket.accept();
inputStreamReader = new InputStreamReader(clientSocket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
message = bufferedReader.readLine();
System.out.println(message);
inputStreamReader.close();
clientSocket.close();
} catch (IOException ex) {
System.out.println("Problem in message reading");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
serverThread.start();
}
}
The problem is, that when the code is in onCreate(), it only gets executed when the service gets created, and I want it to run all the time. So where do I have to put the code in the Service class so it runs all the time?
Best Regards,
Alex
I have made a program to send a message from a client to a server(2 android devices), but the message is not being sent.
Here is the code of the client side application:
package com.example.clientphone;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.os.StrictMode;
import android.view.View;
import android.widget.*;
public class MainActivity extends ActionBarActivity {
private EditText ipaddress , textfield;
private Button send;
private String ip , message;
private Socket client;
private PrintWriter printwriter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ipaddress = (EditText)findViewById(R.id.editText1);
textfield = (EditText)findViewById(R.id.editText2);
send = (Button) findViewById(R.id.button1);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();// enabling strict mode and setting thread policy
StrictMode.setThreadPolicy(policy);
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
message = textfield.getText().toString();
ip = ipaddress.getText().toString();// getting ip address
textfield.setText(" ");
try {
client = new Socket(ip, 5200);// ip address is entered over here....
printwriter = new PrintWriter(client.getOutputStream() , true);// getting the outputstream
printwriter.write(message);// writing the message
printwriter.flush();// flushing the printwriter
printwriter.close();// closing printwriter
client.close();// closing client
} catch (UnknownHostException e) {
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}
});
}
}
Here is the code for server side application. I have chosen the port 5200 to connect on. I want the user to enter the IP address of the other device and not keep it hard-coded:
package com.example.serverphone;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.*;
public class MainActivity extends ActionBarActivity {
TextView message;
private ServerSocket socket;
private Handler UpdateConversationHandler;
Thread ServerThread = null;
public static final int port = 5200;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
message = (TextView)findViewById(R.id.textView1);
UpdateConversationHandler = new Handler();
this.ServerThread = new Thread(new ServerThread());
this.ServerThread.start();
}
#Override
protected void onStop() {
super.onStop();
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread implements Runnable{
#Override
public void run() {
Socket socket2 = null;
try {
socket = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
while(!Thread.currentThread().isInterrupted()){
try {
socket2 = socket.accept();
BufferedReaderThread commThread = new BufferedReaderThread(socket2);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class BufferedReaderThread implements Runnable{
private Socket clientSocket;
private BufferedReader input;
public BufferedReaderThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()){// making sure the thread is not interrupted...
try {
String read = input.readLine();
if(read != null){
UpdateConversationHandler.post(new updateUIConversation(read));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIConversation implements Runnable{
private String msg;
public updateUIConversation(String str){
this.msg = str;
}
#Override
public void run() {
message.setText(message.getText().toString() + msg + "/n");
}
}
}
In your client you are doing network operation on the main thread. Do them in a separate thread. Do not silently supress exceptions and you will see in the log.
new Thread(new Runnable() {
public void run() {
try {
Socket client = new Socket(ip, 5200);
PrintWriter = new PrintWriter(client.getOutputStream() , true);
printwriter.write(message);// writing the message
printwriter.flush();// flushing the printwriter
printwriter.close();// closing printwriter
client.close();// closing client
} catch (Exception x) { Log.e("CLIENT", "Exception " + x); }
}).start();
I am testing socket programming on Android however I am having a problem. The client is basically launched through the main activity with a basic function of sending a message to the server and getting a reply.
the client activity:
package com.test.socket;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class socketActivity extends Activity implements OnClickListener {
String input;
private EditText et;
private ObjectOutputStream oos;
private TextView tv;
private String message;
private ObjectInputStream ois;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try{
InetAddress host = InetAddress.getLocalHost();
Socket socket = new Socket(host.getHostName(),7777);
//send to server
oos = new ObjectOutputStream(socket.getOutputStream());
et = (EditText) findViewById(R.id.text);
Button sendButton = (Button) findViewById(R.id.button);
sendButton.setOnClickListener(this);
//read from server
ois = new ObjectInputStream(socket.getInputStream());
//System.out.println("Message from Server: "+message);
tv = (TextView) findViewById(R.id.textView);
}
catch(UnknownHostException e)
{
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId())
{
case R.id.button:
input = et.getText().toString();
try {
oos.writeObject(input);
ois.close();
oos.close();
message = (String) ois.readObject();
tv.setText("Message from Server: "+message);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
}
The Server class launched separately from JCreator listening to port 7777:
import java.io.*;
import java.lang.*;
import java.net.*;
public class server {
private ServerSocket server;
private int port = 7777;
public server()
{
try{
server = new ServerSocket(port);
}
catch(IOException e)
{
e.printStackTrace();
}
}
public static void main(String args[])
{
server example = new server();
example.handleConnection();
}
public void handleConnection()
{
System.out.println("Waiting for client message...");
while(true)
{
try{
Socket socket = server.accept();
new ConnectionHandler(socket);
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
}
ConnectionHandler class which the Server accesses:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class ConnectionHandler implements Runnable {
private Socket socket;
public ConnectionHandler(Socket socket)
{
this.socket = socket;
Thread t = new Thread(this);
t.start();
}
#Override
public void run() {
// TODO Auto-generated method stub
try{
//receive from client
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
String message = (String) ois.readObject();
System.out.println("Message from client: "+message);
if(message.equals("check"))
{
System.out.println("Checking for malicious interference...");
Thread.sleep(5000);
System.out.println("Status: Files are good.");
}
//send response to client
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
if(message.equals("check"))
{
oos.writeObject("Checking...");
}
else oos.writeObject("Invalid input");
ois.close();
oos.close();
socket.close();
System.out.println("Waiting for client message...");
}
catch(IOException e)
{
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I have tested the code on JCreator and Eclipse through Java application not Android app and it worked perfect. However when I try doing it through the activity, it's not working.
Any ideas?
In Android, localhost would point to the phone/emulator itself. It doesn't point to your server. The following line below is pointing to your Android device/emulator and not your server. You need to get the actual IP of the server to get it working from your Android
InetAddress host = InetAddress.getLocalHost();
Socket socket = new Socket(host.getHostName(),7777);
It works through Java App, because when you execute it from the context of Java Application, the localhost is pointing to the same server location.