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().
Related
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 am developing a client server application. My client is a java application and my server is an android emulator. I want to send message from client to server but no message received on android emulator.
Java Desktop Client Code
Socket s = null;
BufferedReader get = null;
PrintWriter put = null;
try {
s = new Socket("127.0.0.1", 6000);
put = new PrintWriter(s.getOutputStream(), true);
put.println("hi");
}
catch(Exception ex)
{
}
Android Server Code
private ServerSocket serverSocket;
Handler updateConversationHandler;
Thread serverThread = null;
private TextView text;
private EditText textbox;
public static final int SERVERPORT = 6000;
#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");
}
}
Relevant quote from the documentation (scroll down to the section for Network Address Space:
Each instance of the emulator runs behind a virtual router/firewall service
that isolates it from your development machine's network interfaces and settings
and from the internet. An emulated device can not see your development machine
or other emulator instances on the network. Instead, it sees only that it is
connected through Ethernet to a router/firewall.
The virtual router for each instance manages the 10.0.2/24 network address
space — all addresses managed by the router are in the form of 10.0.2.<xx>,
where <xx> is a number. Addresses within this space are pre-allocated by the
emulator/router as follows:
And then they proceed to show the pre-allocated addresses in a table.
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.
I have a simple connection activity:
package com.example.conn08;
import ...;
public class MainActivity extends Activity
{
public static Socket clientSocket;
public static DataOutputStream outToServer;
public static PrintWriter outTest;
public static BufferedReader inToServer;
With PrintWriter outTest I test server's availability:
If the user has no Internet, or the server doesn't work, I put Thread on a pause with Boolean shouldContinue.
private Thread mThread;
private final Object lock = new Object();
private Boolean shouldContinue = true;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mThread = new Thread(new Runnable()
{
public void run()
{
while (true)
{
synchronized(lock)
{
try
{
lock.wait(); // lock the Thread
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
while (shouldContinue)
{
try
{
final String data = inToServer.readLine();
if (data != null)
{
Log.v("data", data);
runOnUiThread(new Runnable()
{
#Override
public void run()
{
String put[] = data.split("#");
//Data parsing
}
});
}
}
catch (IOException e)
{
e.printStackTrace();
}
Check on availability of the server:
try {
if(clientSocket.getInputStream().read() == -1)
{
Log.v("Connection: ", "lost");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
mThread.start();
Connect();
}
public void Connect()
{
shouldContinue = true;
try
{
clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress("localhost", 15780), 30000);
outToServer = new DataOutputStream(clientSocket.getOutputStream());
inToServer = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
outTest = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(clientSocket.getOutputStream())), true);
synchronized(lock)
{
lock.notify();
}
sendUTF("3#kokoko"); //send the message!
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void sendUTF(String str)
{
try
{
byte[] buf = str.getBytes("UTF-8");
outToServer.write(buf, 0, buf.length);
outToServer.writeBytes("\n");
outToServer.flush();
}
catch (IOException e)
{
e.printStackTrace();
outServ.setText("Нет соединения!");
}
}
}
Problem in that when I don't use the
if(clientSocket.getInputStream().read() == -1)
And send data to server like here:
sendUTF("3#kokoko");
All is fine, but if I use it, on server I see this message like
"#kokoko" - I lose the first character of the message and my socket is crushed! Help me please
I want to send a file from client to Server by using Socket Programming.
I unable to transfer this file, client side is giving message OK, server get freeze at serverClient.accept,and only dispalys Listening on
Ip: 10.81.81.125, I am so confused, Kindly help.
Thanks in advance.
Client Code:
public class uploadData extends AsyncTask<String, String, String> {
#Override
public void onPreExecute() {
} catch (Exception e) {
}
}
#Override
protected String doInBackground(String... arg0) {
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
Log.d("ClientActivity", "C: Connecting...");
Socket socket = new Socket(serverAddr, Constants.SERVERPORT);
socket.setSoTimeout(90000);
connected = true;
if (connected) {
try {
Log.d("ClientActivity", "C: Sending command.");
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
.getOutputStream())), true);
try {
// where you issue the commands
File sFile = new File(filePath);
BufferedInputStream buffIn = null;
buffIn = new BufferedInputStream(
new FileInputStream(sFile));
out.print(buffIn);
} catch (Exception e) {
// TODO: handle exception
}
// setText();
// out.println("Hey Server!");
Log.d("ClientActivity", "C: Sent.");
} catch (Exception e) {
Log.e("ClientActivity", "S: Error", e);
}
}
socket.close();
Log.d("ClientActivity", "C: Closed.");
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(SynServer.this,getString(R.string.noServer), Toast.LENGTH_SHORT).show();
connected = false;
}
return null;
}
#Override
protected void onProgressUpdate(String... progress) {
// TODO Auto-generated method stub
super.onProgressUpdate(progress);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
#Override
protected void onDestroy() {
Runtime.getRuntime().gc();
super.onDestroy();
}
}
Server Code:
public class Socket_File_ServerActivity extends Activity {
private TextView serverStatus;
// default ip
public static String SERVERIP = "10.0.2.15";
// designate a port
public static final int SERVERPORT =12345;
private Handler handler = new Handler();
private ServerSocket serverSocket;
Socket client=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
serverStatus = (TextView) findViewById(R.id.server_status);
SERVERIP = getLocalIpAddress();
//
Thread fst = new Thread(new ServerThread());
fst.start();
}
public class ServerThread implements Runnable {
public void run() {
try {
Looper.prepare();
if (SERVERIP != null) {
handler.post(new Runnable() {
public void run() {
serverStatus.setText("Listening on IP: " + SERVERIP);
}
});
serverSocket = new ServerSocket(SERVERPORT);
handler.post(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), serverSocket.getLocalSocketAddress().toString()
, Toast.LENGTH_LONG).show();
serverStatus.append("\n"+serverSocket.getLocalSocketAddress().toString());
}
});
Toast.makeText(getApplicationContext(), serverSocket.getLocalSocketAddress().toString()
, Toast.LENGTH_LONG).show();
serverStatus.append("\n"+serverSocket.getLocalSocketAddress().toString());
while (true) {
// listen for incoming clients
Socket client = serverSocket.accept();
handler.post(new Runnable() {
public void run() {
serverStatus.setText("Connected.");
}
});
try {
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
Log.d("ServerActivity", line);
final String myline=new String(line);
handler.post(new Runnable() {
public void run() {
// tv_chatbox.setText("Client said:="+myline);
// do whatever you want to the front end
// this is where you can be creative
}
});
}
break;
} catch (Exception e) {
handler.post(new Runnable() {
public void run() {
serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones.");
}
});
e.printStackTrace();
}
}
} else {
handler.post(new Runnable() {
public void run() {
serverStatus.setText("Couldn't detect internet connection.");
}
});
}
} catch (final Exception e) {
handler.post(new Runnable() {
public void run() {
serverStatus.setText("Error"+e.getMessage());
}
});
e.printStackTrace();
}
}
}
// gets the ip address of your phone's network
private String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) { return inetAddress.getHostAddress().toString(); }
}
}
} catch (SocketException ex) {
Log.e("ServerActivity", ex.toString());
}
return null;
}
#Override
protected void onStop() {
super.onStop();
try {
// make sure you close the socket upon exiting
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client
public class TCPServer {
//tcp port on local host port
public static final int PORT = 3100;
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
//server socket, can also specify Host Address
serverSocket = new ServerSocket(PORT);
//start listening on port
System.out.println("Listening for clients on port: " + PORT);
} catch (IOException e) {
System.err.println("Could not listen on port: " + PORT);
System.err.println(e.getMessage());
System.exit(-1);
}
//create new thread pool
ThreadPool threadPool = new ThreadPool(2);
//call runnable method on thread pool
threadPool.runTask(startServer(serverSocket));
//join thread pool
threadPool.join();
//close server socket and destroy threadpool
serverSocket.close();
threadPool.destroy();
}
private static Runnable startServer(final ServerSocket socket) {
return new Runnable() {
#Override
public void run() {
//keep looping and looking for data
while (true)
try {
//create new thread
new TCPServerThread(socket.accept()).start();
} catch (IOException e) {
System.out.println("Client got disconnected!" + "\nListening for clients on port: " + PORT);
}
}
};
}
}
Server
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.Socket;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.Player;
public class TCPServerThread extends Thread {
private Socket socket = null;
//constructor
public TCPServerThread(Socket socket) {
this.socket = socket;
}
public void run() {
try {
//read data into buffered stream
BufferedInputStream stream = new BufferedInputStream(
socket.getInputStream());
//create music player object with buffered stream
Player p = new Player(stream);
//start playing
p.play();
//close socket after done playing
socket.close();
} catch (IOException e) {
System.out.println("Client got disconnected!" + "\nListening for clients on port: " + TCPServer.PORT);
} catch (JavaLayerException e) {
System.out.println("Client got disconnected!" + "\nListening for clients on port: " + TCPServer.PORT);
}
}
}
Thread Pool
import java.util.LinkedList;
class ThreadPool extends ThreadGroup {
private boolean isAlive;
private LinkedList<Runnable> taskQueue;
private int threadID;
private static int threadPoolID;
//constructor
public ThreadPool(int numThreads) {
super("ThreadPool-" + (threadPoolID++));
// Changes the daemon status of this thread group.
setDaemon(true);
isAlive = true;
taskQueue = new LinkedList<Runnable>();
for (int i = 0; i < numThreads; i++) {
new PooledThread().start();
}
}
public synchronized void runTask(Runnable task) {
if (!isAlive) {
throw new IllegalStateException();
}
if (task != null) {
taskQueue.add(task);
notify();
}
}
protected synchronized Runnable getTask() throws InterruptedException {
while (taskQueue.size() == 0) {
if (!isAlive) {
return null;
}
wait();
}
return (Runnable) taskQueue.removeFirst();
}
public synchronized void close() {
if (isAlive) {
isAlive = false;
taskQueue.clear();
interrupt();
}
}
public void join() {
// notify all waiting threads that this ThreadPool is no
// longer alive
synchronized (this) {
isAlive = false;
notifyAll();
}
// wait for all threads to finish
Thread[] threads = new Thread[activeCount()];
int count = enumerate(threads);
for (int i = 0; i < count; i++) {
try {
threads[i].join();
} catch (InterruptedException ex) {
}
}
}
private class PooledThread extends Thread {
public PooledThread() {
super(ThreadPool.this, "PooledThread-" + (threadID++));
}
public void run() {
while (!isInterrupted()) {
// get a task to run
Runnable task = null;
try {
task = getTask();
} catch (InterruptedException ex) {
}
// if getTask() returned null or was interrupted,
// close this thread by returning.
if (task == null) {
return;
}
// run the task, and eat any exceptions it throws
try {
task.run();
} catch (Throwable t) {
uncaughtException(this, t);
}
}
}
}
}