Whenever I run my code, I am not being redirected to the next activity when my socket connection is established, instead it moves to else part and shows the fail to connect toast. I know it is connecting correctly, from the output of my other device. Is there something wrong with my IF condition? Or the "Socket != null" was incorrectly used?
public void connecttoserver(View view){
final TextView txtenterlumens;
txtenterlumens = (TextView) findViewById(R.id.txtenterlumens);
if(!txtenterlumens.getText().toString().equals("")) {
enterlumens = Integer.parseInt(txtenterlumens.getText().toString());
new Thread(new ClientThread()).start();
if(socket!=null){
Intent goToNextActivity = new Intent(getApplicationContext(), MainActivity.class);
startActivity(goToNextActivity);
}
else {
Toast.makeText(LoginActivity.this, "Fail to connect!", Toast.LENGTH_LONG).show();
txtenterlumens.setText("");
}
}
else{
Toast.makeText(LoginActivity.this, "Please enter correct Lumens!", Toast.LENGTH_LONG).show();
txtenterlumens.setText("");
}
}
This is my socket creation code:
public class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
setSocket(socket);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
You are creating socket in ClientThread but verifying it in another class, but you dont retrieve it. Add this method to ClientThread:
public boolean isConnected(){
return socket !=null
}
and then slightly edit your connecttoserver to this :
ClientThread ct = new new ClientThread();
new Thread(ct).start();
if(ct.isConnected(){...}
You init socket on another thread, so the result can not get immediately. Let do something like below. I haven't test this code yet.
public void connecttoserver(View view){
final TextView txtenterlumens;
txtenterlumens = (TextView) findViewById(R.id.txtenterlumens);
if(!txtenterlumens.getText().toString().equals("")) {
enterlumens = Integer.parseInt(txtenterlumens.getText().toString());
new Thread(new ClientThread(new EstablishListener() {
public void onEstablishCompleted(Socket socket) {
setSocket(socket);
if(socket!=null){
Intent goToNextActivity = new Intent(getApplicationContext(), MainActivity.class);
startActivity(goToNextActivity);
}
else {
Toast.makeText(LoginActivity.this, "Fail to connect!", Toast.LENGTH_LONG).show();
txtenterlumens.setText("");
}
}
})).start();
}
else{
Toast.makeText(LoginActivity.this, "Please enter correct Lumens!", Toast.LENGTH_LONG).show();
txtenterlumens.setText("");
}
}
public class ClientThread implements Runnable {
EstablishListener mListener = null;
public ClientThread(EstablishListener listner) {
mListener = listner;
}
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
mListener.onEstablishCompleted(socket);
} catch (UnknownHostException e1) {
mListener.onEstablishCompleted(null);
e1.printStackTrace();
} catch (IOException e1) {
mListener.onEstablishCompleted(null);
e1.printStackTrace();
}
}
}
// Create function interface for callback
public interface EstablishListener {
void onEstablishCompleted(Socket socket);
}
Thanks everyone for your help. I decided it would be easiest if I do the check for socket connection and activity changing in the ClientThread instead.
public class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
setSocket(socket);
if(socket!=null){
Intent goToNextActivity = new Intent(getApplicationContext(), MainActivity.class);
startActivity(goToNextActivity);
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
Related
I created a socket program on android studio. First I create it with on the main class and it is working. With the help of this site I separate the connect and disconnect it works. Now there is a problem when the client send a message on the server. Whenever I put a letter, the output is just a blank space.
separate class
public class SocketClient extends Thread {
String serverm = null;
Socket client;
String Socketdata;
Context context;
String message;
String address;
public boolean mRun = true;
private PrintWriter printwriter;
public SocketClient (String address, Context context, String message )
{
this.address = address;
this.context = context;
this.message = message;
}
#Override
public void run(){
mRun = true;
try {
client = new Socket(address, 3818);
BufferedReader mBufferIn = new BufferedReader(
new InputStreamReader(client.getInputStream()));
while (mRun) {
serverm = mBufferIn.readLine();
if (serverm != null) {
System.out.println(serverm);
Socketdata = serverm;
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void stopSocket()
{
if(client !=null)
{
Toast.makeText(context, "disconnected", Toast.LENGTH_LONG).show();
try {
client.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else{
Toast.makeText(context, "socket not found", Toast.LENGTH_LONG).show();
}
}
public void SendSocket()
{
if (message != null) {
try {
printwriter = new PrintWriter(client.getOutputStream(),true);
printwriter.write(message + "\r\n"); // write the message to output stream
printwriter.flush();
}catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Toast.makeText(context, "sent", Toast.LENGTH_LONG).show();
}
}
Main class
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textField = (EditText) findViewById(R.id.message); // reference to the text field
Connect = (Button) findViewById(R.id.connect); // reference to the connect button
Disconnect = (Button) findViewById(R.id.disconnect); // reference to the connect button
Send = (Button) findViewById(R.id.send); // reference to the send button
editTextAddress = (EditText) findViewById(R.id.address); // reference to the address
Disconnect.setOnClickListener(DisconnectOnClickListener);
Connect.setOnClickListener(ConnectOnClickListener);
Send.setOnClickListener(SendOnClickListener);
}
//Button Send
OnClickListener SendOnClickListener = new OnClickListener() {
public void onClick(View v) {
thread.SendSocket();
textField.setText(""); // Reset the text field to blank
}
};
//Button Disconnect
OnClickListener DisconnectOnClickListener = new OnClickListener() {
public void onClick(View v) {
thread.stopSocket();
}
};
//Button Connect
OnClickListener ConnectOnClickListener = new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getApplicationContext(),"connected",Toast.LENGTH_LONG).show();
thread = new SocketClient(editTextAddress.getText().toString(), getApplicationContext(), textField.getText().toString());
thread.start();
}
};
Now I know what I'm missing. sorry for the inconvenience.
separate class
public void SendSocket(String newMessage ) {
if (newMessage != null) {
try {
printwriter = new PrintWriter(socket.getOutputStream(),true);
printwriter.write(newMessage + "\r\n"); // write the message to output stream
printwriter.flush();
}catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
main class
View.OnClickListener SendOnClickListener = new View.OnClickListener() {
public void onClick(View v) {
thread.SendSocket(textField.getText().toString());
}
};
I'm beginer in android and i'm trying develop a connection TCP server.
I have this class:
public class JavaTCPServer {
public static void send(String aMessage) {
final String msg = aMessage;
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Socket socket = null;
try {
ServerSocket serverSocket = GlobalSingleton.getInstance().getServerSocket();
socket = serverSocket.accept();
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.println(msg);
printWriter.flush();
printWriter.close();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
socket = null;
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
});
thread.start();
}
}
private ServerSocket serverSocket; //Created in GlobalSingleton Class...
try {
serverSocket = new ServerSocket(Constantes.TCP_PORT);
} catch (IOException e) {
e.printStackTrace();
}
I can send message normally in the first time, but when i try to send message the second time the software remains in line: socket = serverSocket.accept(); and the message in printWriter.println(msg) is not sent.
Additional Information
When i kill the app in settings and open i can send once.
Any questions don't hesitate ask me.
Thanks for all!
Your code only accepts one connection, processes it, and then exits. It does not behave as you have described.
You need a loop.
You also need to start a separate thread to handle each connection.
And calling a method that accepts connections send() is inside out and back to front.
I solved my own problem.
I wrote my class as the follow bellow code:
public class JavaTCPServer {
private ServerSocket serverSocket;
private String message;
private Handler updateConversationHandler;
private Thread serverThread = null;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public ServerSocket getServerSocket() {
return serverSocket;
}
public void setServerSocket(ServerSocket serverSocket) {
this.serverSocket = serverSocket;
}
public JavaTCPServer() {
setUpdateConversationHandler(new Handler());
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
}
public Handler getUpdateConversationHandler() {
return updateConversationHandler;
}
public void setUpdateConversationHandler(Handler updateConversationHandler) {
this.updateConversationHandler = updateConversationHandler;
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(Constantes.TCP_PORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(
socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
private String messageSend;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.setInput(new BufferedReader(new InputStreamReader(
this.clientSocket.getInputStream())));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
Central central = GlobalSingleton.getInstance()
.get_current_central();
if (central != null) {
if ((central.getStep() <= central.getObjetivo()) &&
(central.getStep() == 99)){
try {
messageSend = getMessage();
PrintWriter printWriter = new PrintWriter(
clientSocket.getOutputStream(), true);
printWriter.println(messageSend);
printWriter.flush();
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
printWriter.println(Constantes.EXIT_CONFIG);
printWriter.flush();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
central.setStep(central.getStep() + 1);
}
}
/*
* try { String read = input.readLine();
* updateConversationHandler.post(new updateUIThread(read)); }
* catch (IOException e) { e.printStackTrace(); }
*/
}
}
public BufferedReader getInput() {
return input;
}
public void setInput(BufferedReader input) {
this.input = input;
}
}
}
With this class you can send and receive tcp messages all the time.
Thanks for all help!
Serversocket.accept() function is for accepting a new client and connecting with the client, for messages you need to use DataInputStream() and DataOutputStream() after connecting with the server. This happens because for the first time server accepts the new client and process further but after this it does not get a new connection and it waits for new connection at serversocket.accept().
I've a simple client and server on android. Everything works fine except when I close the client app then the server stops working the app closes.
I think it's about not closing the socket. But when I close the socket in the client the server still stops working.
I'm running a thread on the server. This is my server code:
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
}
#Override
protected void onStop() {
super.onStop();
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
private boolean feedback = false;
public updateUIThread(String str) {
msg = str;
}
#Override
public void run() {
parseCommand();
if(feedback)
{
textFeedback.setText(msg);
feedback = false;
}
else
{
textTv.setText(msg);
}
}
if(msg != null)
parseCommand();
and in
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
if(read == null)
{
clientSocket.close();
Log.d("Test","SOCKET CLOSED");
return;
}
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
I wish to build a simple peer-peer app using Sockets. A accepts a number and sends it to B. Then B returns the square of the number back to A.
A sends to B on port 6000 and B sends back to A on port 8000. So both the machines act as clients when they must send, and as servers when they must receive.
But isn't it true that a server should be started BEFORE a client ? So, whats the logical solution to making this app ?
Here is the Server's code
package com.javacodegeeks.android.androidsocketserver;
.....
public class Server extends Activity {
private ServerSocket serverSocket;
private Socket clientSock;
Handler updateConversationHandler;
Thread serverThread = null;
Thread clientThread = null;
private TextView text;
public static final int SERVERPORT = 5000;
public static final int CLIENTPORT = 8000;
private static final String CLIENT_IP = "10.0.2.2";
protected IRemote mService;
private boolean bound = false;
Intent it;
private boolean test = false;
private ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
mService = null;
Toast.makeText(getApplicationContext(), "no", Toast.LENGTH_SHORT).show();
Log.d("IRemote", "Binding - Service disconnected");
}
#Override
public void onServiceConnected(ComponentName name, IBinder service)
{
// TODO Auto-generated method stub
mService = IRemote.Stub.asInterface((IBinder) service);
Toast.makeText(getApplicationContext(), "yes", Toast.LENGTH_SHORT).show();
Log.d("IRemote", "Binding is done - Service connected");
}
};
protected void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection);
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.text2);
updateConversationHandler = new Handler();
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
it = new Intent();
it.setAction("com.example.mynewclient.RemoteService");
//it= new Intent(this,IRemote.class);
//TEMP
bound = getApplicationContext().bindService(it, mServiceConnection, Context.BIND_AUTO_CREATE);
Log.d("SERVER", bound ? "Binding is done - Service connected" : "Binding Failed");
this.clientThread = new Thread(new ClientThread());
this.clientThread.start();
}
#Override
protected void onStop() {
super.onStop();
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void onClick(View view) {
try {
// EditText et = findViewById(R.id.text);
String str = text.getText().toString();//et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(clientSock.getOutputStream())),
true);
out.println(345+"\n");
Toast.makeText(getApplicationContext(), "Success", Toast.LENGTH_SHORT).show();
} catch (UnknownHostException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Exception 1", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Exception 2", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Exception 3", Toast.LENGTH_LONG).show();
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
BufferedWriter writer;
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
//writer = new BufferedWriter(new OutputStreamWriter(this.clientSocket.getOutputStream()));
//writer.write("Server Echos to client");
//writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run(){
String message;
BufferedReader input;
if(mService == null)
{
Log.d("TAG 0", "Inside mservice==null");
Intent it = new Intent();
it.setAction("com.example.mynewclient.RemoteService");
//it.setClassName( "com.example.myclient","com.example.myclient.IRemoteService" );
//binding to remote service
// bindService(it, mServiceConnection, Service.BIND_AUTO_CREATE);
}
int f = Integer.parseInt(msg);
try{
//Toast.makeText(getApplicationContext(), "Result -> Add ->"+mIRemoteService.getSum(3,4), Toast.LENGTH_SHORT).show();
message = Integer.toString(mService.getSum(f,f));
text.setText(text.getText().toString()+"The sum is: "+ message + "\n");
}
catch(Exception e)
{
//setContentView(R.layout.activity_main);
System.out.println(e.toString());
Log.e("EXCEPTION 3", e.toString());
f = f+f;
message = "Not Successful";
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
}
}
//TEMP Commented
/*#Override
public void run() {
text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
}*/
}
class ClientThread implements Runnable {
#Override
public void run() {
BufferedReader input;
try {
Log.d("SERVER", "Client - thread 1");
InetAddress serverAddr = InetAddress.getByName(CLIENT_IP);
clientSock = new Socket(serverAddr, SERVERPORT);
//input = new BufferedReader(new InputStreamReader(clientSock.getInputStream()));
/////////////////////
Log.d("SERVER", "Client - thread 2");
//TEMP Commented
//input = new BufferedReader(new InputStreamReader(clientSock.getInputStream()));
input = new BufferedReader(new InputStreamReader(clientSock.getInputStream()));
Log.d("SERVER", "Client - thread 3");
} catch (UnknownHostException e1) {
e1.printStackTrace();
Toast.makeText(getApplicationContext(), "exception 1", Toast.LENGTH_SHORT).show();
} catch (IOException e1) {
e1.printStackTrace();
Toast.makeText(getApplicationContext(), "exception 2", Toast.LENGTH_SHORT).show();
}
}
}
}
Here's the client:
package com.javacodegeeks.android.androidsocketclient;
....
public class Client extends Activity {
private Socket thisSocket;
private ServerSocket serverSocket;
private TextView text;
private static final int SERVERPORT = 6000;
private static final String SERVER_IP = "10.0.2.2";
private static final int CLIENTPORT = 8000;
Handler updateConversationHandler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new ClientThread()).start();
new Thread(new ServerThread()).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(thisSocket.getOutputStream())),
true);
out.println(str);
} catch (UnknownHostException e) {
e.printStackTrace();
Log.e("SERVER ERROR",e.toString());
} catch (IOException e) {
e.printStackTrace();
Log.e("SERVER ERROR",e.toString());
} catch (Exception e) {
e.printStackTrace();
Log.e("SERVER ERROR",e.toString());
}
}
class ClientThread implements Runnable {
#Override
public void run() {
BufferedReader input;
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
thisSocket = new Socket(serverAddr, SERVERPORT);
input = new BufferedReader(new InputStreamReader(thisSocket.getInputStream()));
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
//TEMP COMMENTED
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(CLIENTPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
Log.d("CLIENT TAG", "Listening to server");
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
Log.d("TAG Client 1", "IOException");
}
catch (Exception e)
{
Log.d("TAG Client 2", e.toString());
}
}
Toast.makeText(getApplicationContext(), "Client interrupted", Toast.LENGTH_LONG).show();
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
Log.d("TAG Client 4", "Input from server"+input.toString());
} catch (IOException e) {
Log.d("TAG Client 5", "Input from server");
e.printStackTrace();
}
catch (Exception e)
{
Log.d("TAG Client 6", "Input from server");
}
}
public void run() {
BufferedWriter writer;
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
//writer = new BufferedWriter(new OutputStreamWriter(this.clientSocket.getOutputStream()));
//writer.write("Server Echos to client");
//writer.close();
Log.d("TAG Client 7", "Input from server");
} catch (IOException e) {
e.printStackTrace();
Log.d("TAG Client 8", e.toString());
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run() {
//text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
}
}
The distinction between client and server is not made by who is sending or receiving data. In many cases, both server and client do both. The point of peer-to-peer is that there is no server/client relationship.
That being said, both your applications should run and start listening before you send anything, unless it's always A that sends first, in which case you have a client/server relationship.
Hope that helps.
Edit: Should probably mention this: You usually use multiple threads for networking, to keep listening on at least one port while the rest of the program executes.
There should be a long-connection Server for each client(like A,B,C,D.....),A send msg to Server and forward to D.
I use these codes for communicating between devices. If i close or kill the client app, the server app gets thousands of useless data. The textView in the server side is full of this: Client says: null. If i close the client twice, the server stops with StackOverFlowError. How can i make the code to dont send this null values when the app stops? Or can i filter the server side to do nothing when getting this data?
Client:
public class Client extends Activity {
private Socket socket;
private static final int SERVERPORT = 5000;
private static final String SERVER_IP = "10.0.2.2";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.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);
} 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();
}
}
}
}
Server:
public class Server extends Activity {
private ServerSocket serverSocket;
Handler updateConversationHandler;
Thread serverThread = null;
private TextView text;
public static final int SERVERPORT = 1599;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView) findViewById(R.id.text2);
updateConversationHandler = new Handler();
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
}
#Override
protected void onStop() {
super.onStop();
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run() {
text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
}
}
}
I think you should use a delimiter character, to tell the Server your Client it's about to die. Add that character of code in onPause method of your Android Activity/Fragment.
Then in your Server, just get the String or byte and compare it against your Delimiter String/Character and stop the Server listening for the Connection.
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
The problem is here. You aren't checking the result of readLine() for null. If it returns null, the peer has closed the connection and you should do likewise, and exit this loop. You can probably get rid of the isInterrupted() test as well.
Also, if you get any IOException other that a read timeout when reading from a socket, the connection is dead and you must close the socket and exit your loop.