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.
Related
Sorry for my english. I am trying to create client and server. Now, my logic is like this:
I start app -> start server -> server listening to all messages -> if client sends message to server -> message goes to server -> message received by server -> server needs to send a message to all its customers.
But the server does not do this
** the server needs to send a message to all its customers**
or maybe
the client is not listening to the server.
my question: Why does the client not accept messages from the server?
//Main
//send message
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (sendText.getText().toString().equals("")) {
return;
}
if(chatClientThread==null){
return;
}
chatClientThread.sendMsg(sendText.getText().toString() + "\n");
}
});
//method create server and client, cliend connect to server
createServer(port);
}
public void createServer(int port) {
//create server
ChatServerThread chatServerThread = new ChatServerThread(port);
chatServerThread.start();
//subscribe to server 192.168.31.101 - ip server
createClient("Testov", "192.168.31.101", port);
}
//method for create client
public void createClient(String name, String ipAdress, int SocketServerPORT) {
chatClientThread = new ChatClientThread(
name, ipAdress, SocketServerPORT);
chatClientThread.start();
}
//this is server class
private class ChatServerThread extends Thread {
int SocketServerPORT;
public ChatServerThread(int SocketServerPORT) {
//set port
this.SocketServerPORT = SocketServerPORT;
}
#Override
public void run() {
Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
try {
//create server socket
serverSocket = new ServerSocket(SocketServerPORT);
//waite connect
socket = serverSocket.accept();
Log.e("connect", "server side");
//for input and output
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream = new DataOutputStream(socket.getOutputStream());
//listener
while(true) {
if (dataInputStream.available() > 0) {
//read line
String newMsg = dataInputStream.readUTF();
//send line to client
dataOutputStream.writeUTF(newMsg);
final String ms = newMsg;
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), ms, Toast.LENGTH_SHORT).show();
}
});
//end thread
dataOutputStream.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
//this is client side
private class ChatClientThread extends Thread {
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
String name;
String dstAddress;
int dstPort;
String msgToSend = "";
boolean goOut = false;
String msgLog = "";
ChatClientThread(String name, String address, int port) {
this.name = name;
dstAddress = address;
dstPort = port;
}
#Override
public void run() {
try {
//set ip adress and port
socket = new Socket(dstAddress, dstPort);
//for get and post data
String mesageFromServer = null;
dataInputStream = new DataInputStream(socket.getInputStream());
while(!goOut) {
//wait message from server
mesageFromServer = dataInputStream.readUTF();
//output
Log.e("client", mesageFromServer);
final String ms = mesageFromServer;
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), ms, Toast.LENGTH_SHORT).show();
}
});
msgToSend = "";
}
} catch (UnknownHostException e) {
e.printStackTrace();
final String eString = e.toString();
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, eString, Toast.LENGTH_LONG).show();
Log.e("errror", eString);
}
});
} catch (IOException e) {
e.printStackTrace();
final String eString = e.toString();
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, eString, Toast.LENGTH_LONG).show();
Log.e("errror", eString);
}
});
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
private void sendMsg(String msg){
try {
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.writeUTF(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
private void disconnect(){
goOut = true;
}
}
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 want to create an app in which server and client communicate each other. here the code...
Server Side:
public class MainActivity extends ActionBarActivity {
private ServerSocket serverSocket;
Handler updateConversationHandler;
Thread serverThread = null;
Socket clientSocket;
private TextView text;
EditText edit;
Button b;
public static final int SERVERPORT = 6000;
String TimeStamp;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.out.println("inside onCreate");
text = (TextView) findViewById(R.id.textView1);
updateConversationHandler = new Handler();
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
TimeStamp = new java.util.Date().toString();
b=(Button)findViewById(R.id.button1);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
try
{
EditText et = (EditText) findViewById(R.id.editText1);
String str = et.getText().toString();
text.setText(text.getText().toString()+"Me: "+ str +" On "+TimeStamp+ "\n");
/*
BufferedOutputStream bos=new BufferedOutputStream(socket.getOutputStream());
OutputStreamWriter osw= new OutputStreamWriter(bos,"US-ASCII");
osw.write(str+" "+TimeStamp);
osw.flush();
*/
if(clientSocket==null)
Toast.makeText(MainActivity.this, "null socket", Toast.LENGTH_SHORT).show();
else
{
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(clientSocket.getOutputStream())),
true);
out.println(str);
out.flush();
et.setText("");
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
#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);
serverSocket.setReuseAddress(true);
} 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 aclientSocket)
{
//this.aclientSocket = clientSocket;
clientSocket=aclientSocket;
try {
//this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
this.input = new BufferedReader(new InputStreamReader(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: "+ msg +" On "+TimeStamp+ "\n");
}
}
}
Messages send from client correctly receives to server, Now messages from Server writes to socket but cant read at client.
here the client side:
public class MainActivity extends ActionBarActivity {
private Socket socket;
Handler updateConversationHandler;
private static final int SERVERPORT = 5000;
private static final String SERVER_IP = "10.0.2.2";
TextView text;
Button c;
String TimeStamp;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new ClientThread()).start();
TimeStamp = new java.util.Date().toString();
c=(Button)findViewById(R.id.button1);
text = (TextView) findViewById(R.id.textView1);
c.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try
{
EditText et = (EditText) findViewById(R.id.editText1);
String str = et.getText().toString();
text.setText(text.getText().toString()+"Me: "+ str +"On "+TimeStamp+ "\n");
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(str);
out.flush();
et.setText("");
} 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);
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.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();
Log.d("msg","readString"+read);
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable
{
private String msg;
public updateUIThread(String str)
{
this.msg = str;
System.out.println("message in updateThread "+msg);
}
#Override
public void run()
{
System.out.println("message "+msg);
text.setText(text.getText().toString()+"Server: "+ msg +"On "+TimeStamp+ "\n");
}
}
}
The logcat shows:
D/gralloc_goldfish(1777): Emulator without GPU emulation detected.
W/System.err(1777): java.lang.NullPointerException
W/System.err(1777): at com.example.socketservereg.MainActivity$1.onClick(MainActivity.java:67)
W/System.err(1777): at android.view.View.performClick(View.java:4240)
W/System.err(1777): at android.view.View$PerformClick.run(View.java:17721)
W/System.err(1777): at android.os.Handler.handleCallback(Handler.java:730)
W/System.err(1777): at android.os.Handler.dispatchMessage(Handler.java:92)
W/System.err(1777): at android.os.Looper.loop(Looper.java:137)
W/System.err(1777): at android.app.ActivityThread.main(ActivityThread.java:5103)
W/System.err(1777): at java.lang.reflect.Method.invokeNative(Native Method)
06-17
W/System.err(1777): at java.lang.reflect.Method.invoke(Method.java:525)
W/System.err(1777): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
W/System.err(1777): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
I am a beginner and any help will be appreciated...
In the server you use
socket.getOutputStream()
but it should be
clientSocket.getOutputStream()
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 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.