Unable to verify response from server using Sockets in android - android

I am working on an android chat application based on sockets. I am using the following code to implement this:
NetClient.java
public class NetClient {
/**
* Maximum size of buffer
*/
public static final int BUFFER_SIZE = 2048;
private Socket socket = null;
private PrintWriter out = null;
private BufferedReader in = null;
private String host = null;
private int port = 3000;
// private int port;
/**
* Constructor with Host, Port
*
* #param host
* #param port
*/
public NetClient(String host, int port) {
this.host = host;
this.port = port;
}
private void connectWithServer() {
Log.e("Server", "Connecting with server");
try {
if (socket == null) {
System.out.println("Socket is null");
socket = new Socket(this.host, this.port);
out = new PrintWriter(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void disConnectWithServer() {
Log.e("Server", "Disconnecting with server");
if (socket != null) {
if (socket.isConnected()) {
try {
in.close();
out.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void sendDataWithString(String message) {
Log.e("Send data", "Sendind data to server");
if (message != null) {
connectWithServer();
out.write(message);
out.flush();
}
}
public String receiveDataFromServer() {
Log.e("Receive data", "Receivind data from the server");
try {
String message = "";
int charsRead = 0;
char[] buffer = new char[BUFFER_SIZE];
while ((charsRead = in.read(buffer)) != -1) {
message += new String(buffer).substring(0, charsRead);
}
//Log.e("ServerResponse", message);
disConnectWithServer(); // disconnect server
return message;
} catch (IOException e) {
return "Error receiving response: " + e.getMessage();
}
}
}
ChatActivity.java
public class ChatActivity extends Activity {
private EditText edtMsg;
private Button btnSend;
private String serverIpAddress = "192.168.2.250";
private int port = 3000;
private boolean connected = false;
private Handler handler = new Handler();
private BufferedReader in = null;
private PrintWriter out = null;
public static final int BUFFER_SIZE = 2048; // Max. size of buffer
private Socket socket = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
edtMsg = (EditText) findViewById(R.id.edtMessage);
btnSend = (Button) findViewById(R.id.btnSendMessage);
btnSend.setOnClickListener(connectListener);
}
private View.OnClickListener connectListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(),"clicked",Toast.LENGTH_LONG).show();
Log.e("Button", "Button clicked");
if (!connected) {
if (!serverIpAddress.equals("")) {
Thread cThread = new Thread(new ClientThread());
cThread.start();
}
}
}
};
public class ClientThread implements Runnable {
public void run() {
NetClient nc = new NetClient(serverIpAddress, port);
String message = edtMsg.getText().toString().trim();
Log.e("Msg", message);
nc.sendDataWithString(message);
String response = nc.receiveDataFromServer();
Log.e("Server Response ", response);
}
}
}
I am not able to verify whether the data has been posted to server or not as i am getting unexpected result from the server.
Logcat
E/Server Response﹕ [ 12-01 14:56:01.313 302: 1017 V/qcbassboost ]
I think i am doing some mistake in the use of socket.Please help me to resolve the issue.

Related

TCP Client sends data but TCP server receives null

I have a TCP client and a TCP server class in my app.
The client sends small strings such as "1|2|" or "1|11|"
Client class
public class TcpClient {
private static final int MAX_DATA_RETRY = 1;
private static final int PING_TIMEOUT = 100;
private ClientThread thread;
private boolean mRun = true;
private PrintWriter mBufferOut;
private String mIPAdress;
private ArrayList<BufferDataItem> messageBuffer = new ArrayList<BufferDataItem>();
private Socket mSocket;
public TcpClient()
{
thread = new ClientThread();
thread.start();
}
private class ClientThread extends Thread {
#Override
public void run() {
while(mRun)
{
if(messageBuffer.size() <= 0)
continue;
BufferDataItem currMessage = messageBuffer.get(0);
currMessage.retryCount++;
if(currMessage.retryCount > MAX_DATA_RETRY)
{
messageBuffer.remove(0);
continue;
}
try {
//here you must put your computer's IP address.
InetAddress serverAddr = InetAddress.getByName(currMessage.ip);
//Log.e("TCP Client", "C: Connecting...");
try {
if(!serverAddr.isReachable(PING_TIMEOUT))
{
//only attempt to connect to devices that are reachable
messageBuffer.remove(0);
continue;
}
//create a socket to make the connection with the server
mSocket = new Socket(serverAddr, TcpManager.SERVER_PORT);
//Log.i("TCP Debug", "inside try catch");
//sends the message to the server
mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream())), true);
String message = currMessage.message;
if (mBufferOut != null && !mBufferOut.checkError()) {
Log.d("TCP SEND", "PUTTING IN BUFFER! " + message);
mBufferOut.println(message);
listener.messageSent(message, currMessage.ip);
messageBuffer.remove(0);
}
mBufferOut.flush();
}
catch (ConnectException e) {
//Connection refused by found device!
//Log.e("TCP", "C: ConnectException ip = "+currMessage.ip, e);
listener.hostUnreachable(currMessage.ip);
continue;
}
catch (Exception e) {
Log.e("TCP", "S: Error", e);
listener.messageSendError(e);
}
finally {
if(mSocket != null)
mSocket.close();
}
}
catch (Exception e) {
Log.e("TCP", "C: Error", e);
listener.messageSendError(e);
continue;
}
}
}
}
/**
* Sends the message entered by client to the server
*
* #param message text entered by client
*/
public void sendMessage(String message) {
BufferDataItem data = new BufferDataItem();
data.message = message;
data.ip = mIPAdress;
messageBuffer.add(data);
}
public void sendMessage(String message, String ip) {
mIPAdress = ip;
BufferDataItem data = new BufferDataItem();
data.message = message;
data.ip = mIPAdress;
messageBuffer.add(data);
}
/**
* Close the connection and release the members
*/
public void stopClient() {
Log.i("Debug", "stopClient");
mRun = false;
if (mBufferOut != null) {
mBufferOut.flush();
mBufferOut.close();
}
mBufferOut = null;
}
private class BufferDataItem
{
public String message = "";
public int retryCount = 0;
public String ip = "";
}
private OnMessageSent listener = null;
public interface OnMessageSent {
public void messageSent(String message, String ip);
public void hostUnreachable(String ip);
public void messageSendError(Exception e);
}
public void setMessageSentListener(OnMessageSent listener)
{
this.listener = listener;
}
public void removeMessageSentListener()
{
this.listener = null;
}
}
Server Class
public class TcpServer {
private ServerThread thread;
private boolean mRun = true;
private boolean mEnd = false;
public TcpServer()
{
thread = new ServerThread();
thread.start();
}
private class ServerThread extends Thread {
#Override
public void run() {
try {
Boolean end = false;
ServerSocket ss = new ServerSocket(TcpManager.SERVER_PORT);
while (mRun) {
//Server is waiting for client here, if needed
Socket s = ss.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
//PrintWriter output = new PrintWriter(s.getOutputStream(), true); //Autoflush
String st = input.readLine();
String remoteIP = s.getRemoteSocketAddress().toString();
int index = remoteIP.indexOf(":");
remoteIP = remoteIP.substring(1,index);
Log.d("TCP READ", "TCP READ: " + st);
if(st != null)
listener.messageReceived(st, remoteIP);
//output.println("Good bye and thanks for all the fish :)");
if(mEnd)
{
s.close();
mRun = false;
}
}
ss.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//Declare the interface. The method messageReceived(String message) will must be implemented in the MyActivity
//class at on asynckTask doInBackground
public interface OnMessageReceived {
public void messageReceived(String message, String ip);
}
private OnMessageReceived listener = null;
public void SetMessageReceivedListener(OnMessageReceived listener)
{
this.listener = listener;
}
public void RemoveMessageReceivedListener()
{
this.listener = null;
}
}
This works fine for the first few times it runs and then but then the Client sends "1|11|" and the the server sets st as null during the readLine.
String st = input.readLine();
Does anyone have any suggestions?
I see two possible reason why the server does not receive valid data after some time.
Server does not close the socket s because the mEnd is never set to true. The client open a new TCP connection for each message. The server creates a socket for the connection but it never close the socket and the server side of the connection remains open. It is a resource leak and it may cause the problem.
The client use the ArrayList<BufferDataItem> messageBuffer. ArrayList is not a thread safe collection and messageBuffer is used from more than one thread. It is safe to use synchronizedList here. See the How do I make my ArrayList Thread-Safe? Another approach to problem in Java? or Concurrent threads adding to ArrayList at same time - what happens?

how to repeate sending value by socket

I have this client and server communication program. I got the idea from Android-er website.
This codes send a one random number when the customer pressing the connection button and I want to send new random number of every five minutes when the client had been connected with server.
Client code:
public class MainActivity extends AppCompatActivity {
TextView textResponse;
EditText editTextAddress, editTextPort;
Button buttonConnect, buttonClear;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editTextAddress = (EditText)findViewById(R.id.address);
editTextPort = (EditText)findViewById(R.id.port);
buttonConnect = (Button)findViewById(R.id.connect);
buttonClear = (Button)findViewById(R.id.clear);
textResponse = (TextView)findViewById(R.id.response);
buttonConnect.setOnClickListener(buttonConnectOnClickListener);
buttonClear.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
textResponse.setText("");
}});
}
View.OnClickListener buttonConnectOnClickListener = new View.OnClickListener(){
#Override
public void onClick(View arg0) {
MyClientTask myClientTask = new MyClientTask(
editTextAddress.getText().toString(),
Integer.parseInt(editTextPort.getText().toString()));
myClientTask.execute();
}};
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
MyClientTask(String addr, int port){
dstAddress = addr;
dstPort = port;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
/*
* notice:
* inputStream.read() will block if no data return
*/
while ((bytesRead = inputStream.read(buffer)) != -1){
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
} 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 {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}
}
}
and this is the code of server:
public class MainActivity extends AppCompatActivity {
TextView info, infoip, msg, randGen;
String message = "";
ServerSocket serverSocket;
String vRand="";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
info = (TextView) findViewById(R.id.info);
infoip = (TextView) findViewById(R.id.infoip);
msg = (TextView) findViewById(R.id.msg);
randGen= (TextView)findViewById(R.id.viewRand);
infoip.setText(getIpAddress());
Thread socketServerThread = new Thread(new SocketServerThread());
socketServerThread.start();
}
public String rGenerate() {
Random rand= new Random();
int number= rand.nextInt(500-251)+251;
vRand = String.valueOf(number);
//randGen.setText(vRand);
return vRand;
}
#Override
protected void onDestroy() {
super.onDestroy();
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class SocketServerThread extends Thread {
static final int SocketServerPORT = 8080;
int count = 0;
#Override
public void run() {
try {
serverSocket = new ServerSocket(SocketServerPORT);
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
info.setText("I'm waiting here: "
+ serverSocket.getLocalPort());
}
});
while (true) {
Socket socket = serverSocket.accept();
count++;
message += "#" + count + " from " + socket.getInetAddress()
+ ":" + socket.getPort() + "\n";
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
msg.setText(message);
}
});
SocketServerReplyThread socketServerReplyThread = new SocketServerReplyThread(
socket, count);
socketServerReplyThread.run();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class SocketServerReplyThread extends Thread {
private Socket hostThreadSocket;
int cnt;
SocketServerReplyThread(Socket socket, int c) {
hostThreadSocket = socket;
cnt = c;
}
#Override
public void run() {
OutputStream outputStream;
String num =rGenerate();
try {
outputStream = hostThreadSocket.getOutputStream();
PrintStream printStream = new PrintStream(outputStream);
printStream.print(num);
printStream.close();
message += num + "\n";
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
msg.setText(message);
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
message += "Something wrong! " + e.toString() + "\n";
}
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
msg.setText(message);
}
});
}
}
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 += "SiteLocalAddress: "
+ inetAddress.getHostAddress() + "\n";
}
}
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}
return ip;
}
}
You can use handler to perform tasks at specific delay. I assumed you know how to send the random numbers using sockets so i wont mess socket codes
Button button = (Button) findViewById(R.id.start_button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handler.postDelayed(new Runnable() {
#Override
public void run() {
sendData();
handler.postDelayed(this, 15000);
}
}, 15000);
}
});
private void sendData(){
new Worker().execute();
}
private class Worker extends AsyncTask<Void, Void, String>{
private static final String TAG = "Worker";
#Override
protected String doInBackground(Void... params) {
return "Hello There";
}
#Override
protected void onPostExecute(String s) {
Log.i(TAG, s);
}
}
You can use a Handler to do something in a certain time period. Try this
Handler customHandler = new android.os.Handler();
static final int SOCKET_VERIFY_TIME = 5000; //milliseconds
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
customHandler.postDelayed(updateTimerThread, SOCKET_VERIFY_TIME);
...
}
private Runnable updateTimerThread = new Runnable() {
public void run()
{
if(socket != null) {
if(socket.connected()) {
socket.emit("eventNumber", randNumber);
}
}
customHandler.postDelayed(this, SOCKET_VERIFY_TIME);
}
};
if you want stop updates use this
customHandler.removeCallbacks(updateTimerThread);
In your Client
public class MainActivity extends AppCompatActivity {
TextView textResponse;
EditText editTextAddress, editTextPort;
Button buttonConnect, buttonClear;
Handler customHandler = new android.os.Handler();
static final int SOCKET_VERIFY_TIME = 5000; //milliseconds
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editTextAddress = (EditText)findViewById(R.id.address);
editTextPort = (EditText)findViewById(R.id.port);
buttonConnect = (Button)findViewById(R.id.connect);
buttonClear = (Button)findViewById(R.id.clear);
textResponse = (TextView)findViewById(R.id.response);
buttonConnect.setOnClickListener(buttonConnectOnClickListener);
buttonClear.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
textResponse.setText("");
}});
/***** Events Socket ***********/
socket = IO.socket(new URI(URL_SERVER));
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
yourActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// Socket is connect. Do something here
/******************* Set Handler delay ******************/
customHandler.postDelayed(updateTimerThread, SOCKET_VERIFY_TIME);
/************************************************/
}
});
}
}).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
#Override
public void call(final Object... args) {
runOnUiThread(new Runnable() {
#Override
public void run() {
// Socket is disconnect. Do something here
customHandler.removeCallbacks(updateTimerThread); // stop handler updates
}
});
}
})
}
View.OnClickListener buttonConnectOnClickListener = new View.OnClickListener(){
#Override
public void onClick(View arg0) {
MyClientTask myClientTask = new MyClientTask(
editTextAddress.getText().toString(),
Integer.parseInt(editTextPort.getText().toString()));
myClientTask.execute();
}};
private Runnable updateTimerThread = new Runnable() {
public void run()
{
if(socket != null) {
if(socket.connected()) {
socket.emit("eventNumber", randNumber);
}
}
customHandler.postDelayed(this, SOCKET_VERIFY_TIME);
}
};
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
MyClientTask(String addr, int port){
dstAddress = addr;
dstPort = port;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
/*
* notice:
* inputStream.read() will block if no data return
*/
while ((bytesRead = inputStream.read(buffer)) != -1){
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
} 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 {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}
}
}

Android Studio Client-Server message struggle

I have a server app in android studio and a client app.
Although the client is able to connect to server I can't seem to pass a message through to the client. I am very new to the networking concept so a little help would be much appreciated.
My MainActivity Class:
public class MainActivity extends Activity {
Server server;
TextView infoip, msg;
TextView usersTitle;
EditText userInput;
Button sendButton;
String[] array = {""};
public static ArrayList<String> lst;
ArrayAdapter<String> adapter;
ListView userList;
OutputStream outputStream;
int receivedPort;
InetAddress receivedIP;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
infoip = (TextView) findViewById(R.id.infoip);
msg = (TextView) findViewById(R.id.msg);
userInput = (EditText) findViewById(R.id.userInput);
sendButton = (Button) findViewById(R.id.sendButton);
usersTitle = (TextView) findViewById(R.id.usersTitle);
server = new Server(this);
infoip.setText(server.getIpAddress() + ":" + server.getPort());
userList = (ListView) findViewById(R.id.userList);
lst = new ArrayList<String>(Arrays.asList(array));
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, lst);
userList.setAdapter(adapter);
userList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String selected = userList.getItemAtPosition(position).toString();
msg.append("\n" + selected + " Client Port: " + receivedPort + " Client IP: " + receivedIP );
}
}
);
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String input = userInput.getText().toString();
Socket socket = null;
try {
socket = new Socket("192.168.1.11",receivedPort);
outputStream = new ObjectOutputStream(socket.getOutputStream());
outputStream.write(input.getBytes());
msg.append(socket.getOutputStream().toString());
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public int getClientPort(int port){
receivedPort = port;
return receivedPort;
}
public InetAddress getClientIP(InetAddress ip){
receivedIP = ip;
return receivedIP;
}
#Override
protected void onDestroy() {
super.onDestroy();
server.onDestroy();
}
}
My server class:
public class Server {
MainActivity activity;
ServerSocket serverSocket;
String message = "";
static final int socketServerPORT = 8080;
public Server(MainActivity activity) {
this.activity = activity;
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;
#Override
public void run() {
try {
// create ServerSocket using specified port
serverSocket = new ServerSocket(socketServerPORT);
while (true) {
// block the call until connection is created and return
// Socket object
final Socket socket = serverSocket.accept();
count++;
message += " #" + count + " from " + socket.getInetAddress() + ":" + socket.getPort() + "\n"
+ " Host Name: " + socket.getInetAddress().getHostName() + "\n";
final String host = socket.getInetAddress().getHostName();
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
activity.msg.setText(message);
activity.lst.add(host);
activity.adapter.notifyDataSetChanged();
activity.usersTitle.setText("Connected Users (" + count + ")");
activity.getClientIP(socket.getInetAddress());
activity.getClientPort(socket.getPort());
}
});
SocketServerReplyThread socketServerReplyThread =
new SocketServerReplyThread(socket, count);
socketServerReplyThread.run();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class SocketServerReplyThread extends Thread {
private Socket hostThreadSocket;
int cnt;
SocketServerReplyThread(Socket socket, int c) {
hostThreadSocket = socket;
cnt = c;
}
#Override
public void run() {
OutputStream outputStream;
String msgReply = " Hello from Server, you are #" + cnt;
try {
outputStream = hostThreadSocket.getOutputStream();
PrintStream printStream = new PrintStream(outputStream);
printStream.print(msgReply);
printStream.close();
message += " replied: " + msgReply + "\n";
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
activity.msg.setText(message);
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
message += " Something wrong! " + e.toString() + "\n";
}
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
activity.msg.setText(message);
}
});
}
}
public 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 += " Server running at : " + inetAddress.getHostAddress();
}
}
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += " Something Wrong! " + e.toString() + "\n";
}
return ip;
}
}
My Client MainACtivity:
public class MainActivity extends Activity {
TextView response;
EditText editTextAddress, editTextPort;
Button buttonConnect, buttonClear, callClass;
Intent intent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editTextAddress = (EditText) findViewById(R.id.addressEditText);
editTextPort = (EditText) findViewById(R.id.portEditText);
response = (TextView) findViewById(R.id.responseTextView);
buttonConnect = (Button) findViewById(R.id.connectButton);
buttonClear = (Button) findViewById(R.id.clearButton);
callClass = (Button) findViewById(R.id.callClass);
callClass.setOnClickListener(
new Button.OnClickListener() {
public void onClick (View v){
intent = new Intent(MainActivity.this, ClientInterface.class);
startActivity(intent);
finish();
}
} );
buttonConnect.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Client myClient = new Client("192.168.1.13", 8080, response);
myClient.execute();
}
});
buttonClear.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
response.setText("");
}
});
}
}
My Client class:
package com.example.seth.chat4all_client;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import android.os.AsyncTask;
import android.widget.TextView;
public class Client extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
TextView textResponse;
Client(String addr, int port, TextView textResponse) {
dstAddress = addr;
dstPort = port;
this.textResponse = textResponse;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(
1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
/*
* notice: inputStream.read() will block if no data return
*/
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
} 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 {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}
}
When a message is sent to the client I get this error message:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.seth.chat4all, PID: 9296
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147)
at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:110)
at libcore.io.IoBridge.connectErrno(IoBridge.java:137)
at libcore.io.IoBridge.connect(IoBridge.java:122)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:163)
at java.net.Socket.startupSocket(Socket.java:590)
at java.net.Socket.tryAllAddresses(Socket.java:128)
at java.net.Socket.<init>(Socket.java:178)
at java.net.Socket.<init>(Socket.java:150)
at com.example.seth.chat4all.MainActivity$2.onClick(MainActivity.java:83)
at android.view.View.performClick(View.java:4789)
at android.view.View$PerformClick.run(View.java:19881)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5294)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
You are trying to do networking on the main thread, which will block any UI actions,
see How to fix android.os.NetworkOnMainThreadException? for the solution to this

Android send received data from a socket service to Activity

I am looking for a way to send received data (receive while flag is set) from a socket service to an activity that is bound to the service. What is the best way to do this ? Handlers , AsyncTask or something else ?
this is the SocketClass I am using to start a connection and handle the incoming messages :
class connectSocket implements Runnable {
#Override
public void run() {
running= true;
try {
socket = new Socket(serverAddr, SERVERPORT);
try {
mBufferOut = new ObjectOutputStream(socket.getOutputStream());
mBufferIn = new ObjectInputStream(socket.getInputStream());
while(running){
msg = (Message) mBufferIn.readObject();
}
}
catch (Exception e) {
Log.e("TCP", "S: Error", e);
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
}
}
}
Update :
public class SocketService extends Service {
private static final String TAG = "com.oos.kiesa.chat";
public static final String SERVERIP = "192.168.X.X";
public static final int SERVERPORT = 4444;
private ObjectOutputStream mBufferOut;
private ObjectInputStream mBufferIn;
Socket socket;
InetAddress serverAddr;
boolean mRun;
Object msg;
public Integer command;
#Override
public IBinder onBind(Intent intent) {
return myBinder;
}
private final IBinder myBinder = new LocalBinder();
public class LocalBinder extends Binder {
public SocketService getService() {
return SocketService.this;
}
}
#Override
public void onCreate() {
super.onCreate();
}
public void IsBoundable(){
Toast.makeText(this,"is boundable", Toast.LENGTH_LONG).show();
}
public void sendMessage(String message) throws IOException {
if (mBufferOut != null) {
mBufferOut.writeObject(message);
mBufferOut.flush();
}
}
public void sendMessage(Message message) throws IOException {
if (mBufferOut != null) {
mBufferOut.writeObject(message);
mBufferOut.flush();
}
}
public void sendMessage(User user) throws IOException {
if (mBufferOut != null) {
mBufferOut.writeObject(user);
mBufferOut.flush();
}
}
public void sendMessage(int command) throws IOException {
if (mBufferOut != null) {
mBufferOut.writeInt(command);
mBufferOut.flush();
}
}
#Override
public int onStartCommand(Intent intent,int flags, int startId){
super.onStartCommand(intent, flags, startId);
System.out.println("I am in on start");
Runnable connect = new connectSocket();
new Thread(connect).start();
return START_STICKY;
}
public void stopClient() throws IOException{
if (mBufferOut != null) {
mBufferOut.flush();
mBufferOut.close();
}
mBufferIn = null;
mBufferOut = null;
socket.close();
}
class connectSocket implements Runnable {
#Override
public void run() {
mRun = true;
try {
socket = new Socket(serverAddr, SERVERPORT);
try {
mBufferOut = new ObjectOutputStream(socket.getOutputStream());
mBufferIn = new ObjectInputStream(socket.getInputStream());
while(mRun){
switch(command.intValue()){
case Constants.ADD_MESSAGE:
msg = (Message) mBufferIn.readObject(); // send message to Activity
break;
}
}
}
catch (Exception e) {
Log.e("TCP", "S: Error", e);
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
}
}
}
#Override
public void onDestroy() {
super.onDestroy();
try {
socket.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
socket = null;
}
}
Some guidance / examples would be greatly appreciated
I am sending you mine, hope it will help :
class SocketRequestHandler extends Thread {
static String EOF = "<EOF>";
TCPResponseModel tcpResponseDS;
Activity activity;
boolean doSkip = false;
String responseStringComplete = "";
Socket clientSocekt;
OutputStream clientSocketOutputStream;
PrintWriter clinetSocketPrintWriter;
DataInputStream clientSocketInputStream;
private SocketRequestHandler(TCPResponseModel tcpResponseDS, Activity activity, SaloonListener listener) {
this.tcpResponseDS = tcpResponseDS;
this.activity = activity;
this.listener = listener;
moreStores = tcpResponseDS.StoresFound;
}
public static SocketRequestHandler pingAll(Activity activity, TCPResponseModel tcpResponseDS, SaloonListener listener) {
SocketRequestHandler requestHandler = new SocketRequestHandler(tcpResponseDS, activity, listener);
requestHandler.start();
return requestHandler;
}
private void closeStreams() {
try {
clientSocekt.close();
clientSocketInputStream.close();
clinetSocketPrintWriter.close();
clientSocketOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void run() {
try {
String pingingHost = "URL_TO_PING";
clientSocekt = new Socket(pingingHost, 12000);
clientSocketOutputStream = clientSocekt.getOutputStream();
clinetSocketPrintWriter = new PrintWriter(clientSocketOutputStream);
String firstPing = "{\"RequestId\":" + tcpResponseDS.RequestId + "}<EOF>";
clinetSocketPrintWriter.println(firstPing);
clinetSocketPrintWriter.flush();
byte[] bytes;
String pingStr = "";
clientSocketInputStream = new DataInputStream(clientSocekt.getInputStream());
while (true) {
bytes = new byte[1024];
clientSocketInputStream.read(bytes);
bytes = trim(bytes);
if (bytes.length > 0 && !doSkip) {
String newString = new String(bytes, "UTF-8");
String decoded = pingStr + newString;
pingStr = checkForMessage(decoded);
responseStringComplete += newString;
}
if (doSkip) {
break;
}
}
closeStreams();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.print(responseStringComplete);
}
}
}
To broadcast chat data just do :
msg = (Message) mBufferIn.readObject(); // Do code after this line
Intent localIntent = new Intent("CHAT_MESSAGE");
localIntent.putExtra("message", msg);
LocalBroadcastManager.getInstance(context).sendBroadcast(localIntent);
Now in the activity where you are showing the chat list you can do
class ReceiveMessages extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals("CHAT_MESSAGE")) {
runOnUiThread(new Runnable() {
#Override
public void run() {
String chatMessage = getIntent().getStringExtra("message");
//get data from intent and update your chat list.
}
});
}
}
}
ReceiveMessages myReceiver;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//your code
myReceiver = new ReceiveMessages();
}
#Override
protected void onStart() {
super.onStart();
LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver,
new IntentFilter("CHAT_MESSAGE"));
}
#Override
protected void onStop() {
super.onStop();
LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);
}
public class AsyncHttpClient {
public AsyncHttpClient() {
}
public static class SocketIORequest {
private String mUri;
private String mEndpoint;
private List<BasicNameValuePair> mHeaders;
public SocketIORequest(String uri) {
this(uri, null);
}
public SocketIORequest(String uri, String endpoint) {
this(uri, endpoint, null);
}
public SocketIORequest(String uri, String endpoint, List<BasicNameValuePair> headers) {
mUri = Uri.parse(uri).buildUpon().encodedPath("/socket.io/1/").build().toString();
mEndpoint = endpoint;
mHeaders = headers;
}
public String getUri() {
return mUri;
}
public String getEndpoint() {
return mEndpoint;
}
public List<BasicNameValuePair> getHeaders() {
return mHeaders;
}
}
public static interface StringCallback {
public void onCompleted(final Exception e, String result);
}
public static interface WebSocketConnectCallback {
public void onCompleted(Exception ex, WebSocketClient webSocket);
}
public void executeString(final SocketIORequest socketIORequest, final StringCallback stringCallback) {
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
AndroidHttpClient httpClient = AndroidHttpClient.newInstance("android-websockets-2.0");
HttpPost post = new HttpPost(socketIORequest.getUri());
addHeadersToRequest(post, socketIORequest.getHeaders());
try {
HttpResponse res = httpClient.execute(post);
String responseString = readToEnd(res.getEntity().getContent());
if (stringCallback != null) {
stringCallback.onCompleted(null, responseString);
}
} catch (IOException e) {
if (stringCallback != null) {
stringCallback.onCompleted(e, null);
}
} finally {
httpClient.close();
httpClient = null;
}
return null;
}
private void addHeadersToRequest(HttpRequest request, List<BasicNameValuePair> headers) {
if (headers != null) {
Iterator<BasicNameValuePair> it = headers.iterator();
while (it.hasNext()) {
BasicNameValuePair header = it.next();
request.addHeader(header.getName(), header.getValue());
}
}
}
}.execute();
}
private byte[] readToEndAsArray(InputStream input) throws IOException {
DataInputStream dis = new DataInputStream(input);
byte[] stuff = new byte[1024];
ByteArrayOutputStream buff = new ByteArrayOutputStream();
int read = 0;
while ((read = dis.read(stuff)) != -1) {
buff.write(stuff, 0, read);
}
return buff.toByteArray();
}
private String readToEnd(InputStream input) throws IOException {
return new String(readToEndAsArray(input));
}

Android background service to connect TCP server and handle message

According to an google example, i write an android client for a connection protocol based on TCP Socket server can send and receive information and it works good. But now I want it to become a background service for these transactions, after I left the application it also can notify me the message in time, I think a couple of days, but without success, someone can give me some help? Very grateful!
MainActivity
public class MainActivity extends Activity implements
Handler.Callback, ChatFragment.MessageTarget {
public static final String TAG = "rolingbaby";
public static final int MESSAGE_READ = 0x400 + 1;
public static final int MESSAGE_SEND = 0x400 + 2;
public static final String SERVER_URL = "192.168.191.2";
public static final int SERVER_PORT = 7838;
private Handler handler = new Handler(this);
private ChatFragment chatFragment;
public Handler getHandler() {
return handler;
}
public void setHandler(Handler handler) {
this.handler = handler;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
InetAddress address = InetAddress.getByName(SERVER_URL);
Log.d(TAG, "Connected success!");
new MyTask1(((ChatFragment.MessageTarget) this).getHandler(),
address).execute();
} catch (UnknownHostException e) {
e.printStackTrace();
}
chatFragment = new ChatFragment();
getFragmentManager().beginTransaction()
.add(R.id.container, chatFragment, "trans")
.commit();
}
#Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
Log.d(TAG, readMessage);
(chatFragment).pushMessage("Rec: " + readMessage);
break;
case MESSAGE_SEND:
Object obj = msg.obj;
(chatFragment).setChatManager((ChatManager) obj);
}
return true;
}
#Override
protected void onPause() {
super.onPause();
finish();
}
}
Pivotal code in ChatFragment
public interface MessageTarget {
public Handler getHandler();
}
public void setChatManager(ChatManager obj) {
chatManager = obj;
}
public void pushMessage(String readMessage) {
adapter.add(readMessage);
adapter.notifyDataSetChanged();
}
MyTask
public class MyTask extends AsyncTask<Void, Void, Void>{
private static final String TAG = "ClientSocketHandler";
private Handler handler;
private ChatManager chat;
private InetAddress mAddress;
private static final int timeOut = 5000;
public MyTask(Handler handler, InetAddress serverAddress) {
this.handler = handler;
this.mAddress = serverAddress;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
Socket socket = new Socket();
try {
socket.bind(null);
socket.connect(new InetSocketAddress(mAddress.getHostAddress(),
MainActivity.SERVER_PORT), timeOut);
Log.d(TAG, "Launching the I/O handler");
chat = new ChatManager(socket, handler);
new Thread(chat).start();
} catch (IOException e) {
e.printStackTrace();
try {
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
return null;
}
public ChatManager getChat() {
return chat;
}
}
ChatManager
public class ChatManager implements Runnable {
private Socket socket = null;
private Handler handler;
public ChatManager(Socket socket, Handler handler) {
this.socket = socket;
this.handler = handler;
}
private InputStream iStream;
private OutputStream oStream;
private static final String TAG = "ChatHandler";
public static String readMessage;
#Override
public void run() {
try {
iStream = socket.getInputStream();
oStream = socket.getOutputStream();
byte[] buffer = new byte[1024];
int bytes;
handler.obtainMessage(MainActivity.MESSAGE_SEND, this)
.sendToTarget();
while (true) {
try {
// Read from the InputStream
bytes = iStream.read(buffer);
if (bytes == -1) {
break;
}else{
readMessage = new String(buffer, "UTF-8");
}
// Send the obtained bytes to the UI Activity
Log.d(TAG, "Rec:" + String.valueOf(buffer));
handler.obtainMessage(MainActivity.MESSAGE_READ,
bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void write(byte[] buffer) {
try {
oStream.write(buffer);
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
}

Categories

Resources