I'm working on a small code that uses socket communications on Java and I'm trying to do the following:
Receive a JSON object and parse it [Done]
If the command received was login then start a login [Done]
Print out to the socket the result of the login procedure
It's the last portion I'm having trouble with, my code is as follows:
public class LoginActivity extends Activity {
private Button btnLogin;
private Button btnDemo;
private EditText edtLogin;
private EditText edtSenha;
private ProgressDialog pd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
btnLogin = (Button)findViewById(R.id.btnLogin);
btnDemo = (Button)findViewById(R.id.btnDemo);
edtLogin = (EditText)findViewById(R.id.edtLogin);
edtSenha = (EditText)findViewById(R.id.edtSenha);
pd = new ProgressDialog(this);
new Thread(new Runnable(){
public void run(){
try {
String inMsg;
JSONObject fromClient;
String cmd;
JSONArray args;
ServerSocket server;
Socket client;
BufferedReader in;
PrintWriter out;
//TODO: Getting reconnects on a proper method
System.out.println("Waiting for client on port 8888");
server = new ServerSocket(8888);
client = server.accept();
System.out.println("Just connected to " + client.getRemoteSocketAddress());
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
while(true)
{
inMsg = in.readLine();
if (inMsg == null)
{
System.out.println("Waiting for client on port 8888");
client = server.accept();
System.out.println("Just connected to " + client.getRemoteSocketAddress());
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
continue;
}
fromClient = new JSONObject(inMsg);
System.out.println("In: " + fromClient);
cmd = fromClient.getString("command");
args = new JSONArray(fromClient.getString("args"));
if(cmd.equals("login")){
final String login = args.getString(0);
final String pwd = args.getString(1);
AndroidUtil.mostrarProgressoAguarde(LoginActivity.this, pd);
new Thread(new Runnable() {
public void run() {
PagPop.getInstance().logar(LoginActivity.this, login, pwd, new ServidorListener<Cliente>() {
#Override
public void recebeuResposta(String mensagem, RespostaServidor<Cliente> resposta) {
handleResposta(mensagem, resposta);
}
});
}
}).start();
//out.println(mensagem);
}
else
{
out.println("Received");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
btnLogin.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
final String login = edtLogin.getText().toString();
final String senha = edtSenha.getText().toString();
System.out.print("Tentando Logar");
AndroidUtil.mostrarProgressoAguarde(LoginActivity.this, pd);
new Thread(new Runnable() {
public void run() {
PagPop.getInstance().logar(LoginActivity.this, login, senha, new ServidorListener<Cliente>() {
#Override
public void recebeuResposta(String mensagem, RespostaServidor<Cliente> resposta) {
handleResposta(mensagem, resposta);
}
});
}
}).start();
}
});
Near the middle of the code there is my failed attempt to print out the desired variable at //out.println(mensagem); If I try to compile my code with that the following happens:
[javac] /android/demo/LoginActivity.java:107: error: local variable out is accessed from within inner class; needs to be declared final
[javac] out.println(mensagem);
How can I either transport that variable mensagem out of there so I can out.println it from the if level or access out from that method without making out final?
Declare PrintWriter out as a global variable in the activity / fragment
Related
I have a server set up on my PC (using Hercules), which is listening on a port # and waiting for a connection. I can't get the android app to receive messages from the server however on my android emulator (Strangely I can send messages to the server), and I can't do either from my physical android phone.
All the examples I'm finding online involve android devices connecting to each other, like this one: https://www.coderzheaven.com/2017/05/01/client-server-programming-in-android-send-message-to-the-client-and-back/
Would I still be able to connect to a PC by just implementing the client side on my android app? What changes would I have to make otherwise?
Directly copy pasting hasn't worked for me...
(Btw the phone and PC are both connected to the same ethernet network, not wifi if that makes a difference)
Thanks!
edit: Turns out my PC was on a different subnet from my phyiscal android phone, and so changing the PC to be on the same subnet as the phone fixed the problem of my phone not being able to even connect, but now it can connect it seems and send messages to the PC, but again not able to receive messages from the hercules server
edit2: My client code (android app)
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
public static final int SERVERPORT = xxxx;
public static final String SERVER_IP = "xxx.xxx.x.xxx";
private ClientThread clientThread;
private Thread thread;
private LinearLayout msgList;
private Handler handler;
private int clientTextColor;
private EditText edMessage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("Client");
clientTextColor = ContextCompat.getColor(this, R.color.colorAccent);
handler = new Handler();
msgList = findViewById(R.id.msgList);
edMessage = findViewById(R.id.edMessage);
}
public TextView textView(String message, int color) {
if (null == message || message.trim().isEmpty()) {
message = "<Empty Message>";
}
TextView tv = new TextView(this);
tv.setTextColor(color);
tv.setText(message + " [" + getTime() + "]");
tv.setTextSize(20);
tv.setPadding(0, 5, 0, 0);
return tv;
}
public void showMessage(final String message, final int color) {
handler.post(new Runnable() {
#Override
public void run() {
msgList.addView(textView(message, color));
}
});
}
#Override
public void onClick(View view) {
if (view.getId() == R.id.connect_server) {
msgList.removeAllViews();
showMessage("Connecting to Server...", clientTextColor);
clientThread = new ClientThread();
thread = new Thread(clientThread);
thread.start();
showMessage("Connected to Server...", clientTextColor);
return;
}
if (view.getId() == R.id.send_data) {
String clientMessage = edMessage.getText().toString().trim();
showMessage(clientMessage, Color.BLUE);
if (null != clientThread) {
clientThread.sendMessage(clientMessage);
}
}
}
class ClientThread implements Runnable {
private Socket socket;
private BufferedReader input;
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
this.input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (true) {
String message = input.readLine();
if (null == message || "Disconnect".contentEquals(message)) {
Thread.interrupted();
message = "Server Disconnected.";
showMessage(message, Color.RED);
break;
}
showMessage("Server: " + message, clientTextColor);
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
void sendMessage(final String message) {
new Thread(new Runnable() {
#Override
public void run() {
try {
if (null != socket) {
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
String getTime() {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
return sdf.format(new Date());
}
#Override
protected void onDestroy() {
super.onDestroy();
if (null != clientThread) {
clientThread.sendMessage("Disconnect");
clientThread = null;
}
}
}
I found a tutorial on the internet that allows a client(android app) - server(java on netbeans) socket that allows me to send and recieve data/string on either side. The user will have to manually enter the data onto an EditText and then pressing the button send with an on click method.
MainActivity
public class MainActivity extends AppCompatActivity {
EditText e1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
e1 = (EditText) findViewById(R.id.etMessage);
Thread myThread = new Thread(new MyServerThread());
myThread.start();
}
class MyServerThread implements Runnable{
Socket s;
ServerSocket ss;
InputStreamReader isr;
BufferedReader bufferedReader;
Handler h = new Handler();
String message;
#Override
public void run() {
try{
ss = new ServerSocket(2222);
while(true){
s = ss.accept();
isr = new InputStreamReader(s.getInputStream());
bufferedReader = new BufferedReader(isr);
message = bufferedReader.readLine();
h.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),message, Toast.LENGTH_SHORT).show();
}
});
}
}catch (IOException e){
e.printStackTrace();
}
}
}
public void send(View v){
MessageSender messageSender = new MessageSender();
messageSender.execute(e1.getText().toString());
}
}
MessageSender
public class MessageSender extends AsyncTask<String,Void,Void>{
Socket s;
DataOutputStream dos;
PrintWriter pw;
#Override
protected Void doInBackground(String... voids) {
String message = voids[0];
try{
s = new Socket("192.168.254.105",2222);
pw = new PrintWriter(s.getOutputStream());
pw.write(message);
pw.close();
s.close();
}catch (IOException e){
e.printStackTrace();
}
return null;
}
}
Now what I am trying to do next is instead of manually typing into the GUI the text and pressing the send button, I want to to send a string on a TextView from another activity let's say Activity1.class to MainActivity.class using the following codes.(the show Textview conatains the text "Hello")
String message = show.getText().toString();
Intent intent= new Intent(Activity1.this, MainActivity.class);
intent.putExtra("message_key", message);
startActivity(intent);
Ans will call it on the Main Activity with
String message = getIntent().getStringExtra("message_key");
passedMessage = (TextView)findViewById(R.id.tvPassed);
passedMessage.setText(message);
Problem is after running the program, the passed string to textview on MainActivity will only display on the gui but will not send to the socket itself. Any idea how to make it work?
In the second activity you can:
String message = getIntent().getStringExtra("message_key");
passedMessage = (TextView)findViewById(R.id.tvPassed);
if(message != null && !message.isEmpty()) {
passedMessage.setText(message);
sendButton.performClick();
}
And make sure to assign the ActionListener of the button before you call performClick
I have simple Java server:
public class Main {
public static void main(String[] args) throws IOException {
System.out.println("Welcome to Server side");
BufferedReader in;
PrintWriter out;
ServerSocket servers = null;
Socket fromClient = null;
// create server socket
try {
servers = new ServerSocket(4444);
} catch (IOException e) {
System.out.println("Couldn't listen to port 4444");
System.exit(-1);
}
try {
System.out.print("Waiting for a client...");
fromClient = servers.accept();
System.out.println("Client connected");
} catch (IOException e) {
System.out.println("Can't accept");
System.exit(-1);
}
in = new BufferedReader(new InputStreamReader(fromClient.getInputStream()));
out = new PrintWriter(fromClient.getOutputStream(), true);
String input;
System.out.println("Wait for messages");
while ((input = in.readLine()) != null) {
if (input.equalsIgnoreCase("exit")) break;
out.println("S ::: " + input);
System.out.println(input);
}
out.close();
in.close();
fromClient.close();
servers.close();
}
}
and simple Android client:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.editText);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
new MyAsync().execute();
}
---------------------
public class MyAsync extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
try {
fromServer = new Socket("192.168.0.103",4444);
in = new BufferedReader(new InputStreamReader(fromServer.getInputStream()));
out = new PrintWriter(fromServer.getOutputStream(), true);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
-------------------
#Override
public void onClick(View v) {
if (v.getId() == R.id.button){
out.println(editText.getText().toString());
}
}
All work good. I send message from Android to server and sever print this message in console. But I want send Object, for example User:
public class User {
private int age;
private String fio;
public User() {
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getFio() {
return fio;
}
public void setFio(String fio) {
this.fio = fio;
}
In Android i can write:
User user = new User();
out.print(user);
But i am not understanding that how can i read this on server side?
You can't do it with print(). Use an ObjectOutputStream.writeObject() at the sender, and ObjectInputStream.readObject() at the receiver. You will need to adjust your User class to implement Serializable and provide a private static long serialVersionUID value.
NB Don't write code like this. Code that depends on the success of code in a try block should be inside the same try block.
I made a simple prototype of a client-server application on Android
I managed to connect two clients to the server and the server can receive their messages. The problem now is that I can't seem to broadcast/receive the messages to other clients.
I try to broadcast the received message through a for loop in the Server class:
private void broadcastMessage(String message) {
for (int i = 0, j = clients.size(); i <= j; i++) {
PrintWriter out = null;
Socket socket = clients.get(i);
try {
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// WHERE YOU ISSUE THE COMMANDS
out.println(message);
Log.d("SERVER Loop", "Broadcasting messages...");
out.close();
}
Log.d("SERVER", "Message Brodcasted");
}
This I then try to receive through a listener in the Client class :
public class ClientThreadListener implements Runnable {
protected Socket serverSocket = null;
protected String mMsgFromServer;
public ClientThreadListener(Socket serverSocket) {
this.serverSocket = serverSocket;
}
public void run() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
serverSocket.getInputStream()));
while ((mMsgFromServer = in.readLine()) != null) {
Log.d("MESSAGE FROM SERVER: ", mMsgFromServer);
handler.post(new Runnable() {
#Override
public void run() {
msgFromOtherClients.append('\n'
+ "Message From Server: " + mMsgFromServer);
}
});
}
} catch (Exception e) {
Log.e("ClientListener", "C: Error", e);
connected = false;
}
}
}
I don't get any errors or force closes though. Forgive me I know it is very messy but please bear with me and please focus on the issue at hand instead :D
Here is the full code for the Server class
public class Server extends Activity {
private TextView serverStatus;
// DEFAULT IP
public static String SERVERIP = "10.0.2.15";
// DESIGNATE A PORT
public static final int SERVERPORT = 8080;
private Handler handler = new Handler();
private ServerSocket serverSocket;
private String mMsgFromClient;
private MultiThreadedServer server;
private ArrayList<Socket> clients = new ArrayList<Socket>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.server);
serverStatus = (TextView) findViewById(R.id.server_status);
// SERVERIP = getLocalIpAddress();
server = new MultiThreadedServer(8080);
new Thread(server).start();
}
public class MultiThreadedServer implements Runnable {
protected int serverPort = 8080;
protected ServerSocket serverSocket = null;
protected boolean isStopped = false;
protected Thread runningThread = null;
public MultiThreadedServer(int port) {
this.serverPort = port;
}
public void run() {
synchronized (this) {
this.runningThread = Thread.currentThread();
}
openServerSocket();
while (!isStopped()) {
Socket clientSocket = null;
try {
clientSocket = this.serverSocket.accept();
clients.add(clientSocket);
} catch (IOException e) {
if (isStopped()) {
Log.d("SERVER TEXT", "Server Stopped.");
return;
}
throw new RuntimeException(
"Error accepting client connection", e);
}
new Thread(new WorkerRunnable(clientSocket, this)).start();
}
Log.d("SERVER TEXT", "Server Stopped.");
}
private synchronized boolean isStopped() {
return this.isStopped;
}
public synchronized void stop() {
this.isStopped = true;
try {
this.serverSocket.close();
} catch (IOException e) {
throw new RuntimeException("Error closing server", e);
}
}
private void openServerSocket() {
try {
this.serverSocket = new ServerSocket(this.serverPort);
} catch (IOException e) {
throw new RuntimeException("Cannot open port 8080", e);
}
}
private void broadcastMessage(String message) {
for (int i = 0, j = clients.size(); i <= j; i++) {
PrintWriter out = null;
Socket socket = clients.get(i);
try {
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// WHERE YOU ISSUE THE COMMANDS
out.println(message);
Log.d("SERVER Loop", "Broadcasting messages...");
out.close();
}
Log.d("SERVER", "Message Brodcasted");
}
}
public class WorkerRunnable implements Runnable {
protected Socket clientSocket = null;
protected String mMsgFromClient = null;
private UUID id;
public WorkerRunnable(Socket clientSocket, MultiThreadedServer server) {
this.clientSocket = clientSocket;
id = UUID.randomUUID();
}
public void run() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
while ((mMsgFromClient = in.readLine()) != null) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.append('\n'
+ "Message From Client ID " + getID()
+ ": " + mMsgFromClient);
}
});
}
Log.d("SERVERTEXT", "Proceed to broadcast");
server.broadcastMessage(mMsgFromClient);
} catch (IOException e) {
Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
serverStatus
.append('\n'
+ "Message From Client ID "
+ getID()
+ ": "
+ "Oops. Connection interrupted. Please reconnect your phones.");
}
});
e.printStackTrace();
}
}
private String getID() {
return id.toString();
}
}
}
Here is the full code for the Client class
public class Client extends Activity {
private EditText serverIp;
private EditText chatMsg;
private Button connectPhones;
private Button sendMsg;
private TextView msgFromOtherClients;
private String serverIpAddress = "";
private boolean connected = false;
private boolean willSendMsg = false;
private Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.client);
serverIp = (EditText) findViewById(R.id.server_ip);
connectPhones = (Button) findViewById(R.id.connect_phones);
connectPhones.setOnClickListener(connectListener);
chatMsg = (EditText) findViewById(R.id.chat_msg);
sendMsg = (Button) findViewById(R.id.send_msg);
sendMsg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
willSendMsg = true;
}
});
msgFromOtherClients = (TextView) findViewById(R.id.msg_from_other_clients);
}
private OnClickListener connectListener = new OnClickListener() {
#Override
public void onClick(View v) {
if (!connected) {
serverIpAddress = serverIp.getText().toString();
if (!serverIpAddress.equals("")) {
Thread cThread = new Thread(new ClientThread());
cThread.start();
}
}
}
};
public class ClientThread implements Runnable {
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
Log.d("ClientActivity", "C: Connecting...");
Socket socket = new Socket(serverAddr, Server.SERVERPORT);
connected = true;
Thread listener = new Thread(new ClientThreadListener(new Socket(serverAddr, Server.SERVERPORT)));
listener.start();
while (connected) {
if (willSendMsg) {
willSendMsg = false;
try {
Log.d("ClientActivity", "C: Sending command.");
PrintWriter out = new PrintWriter(
new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream())), true);
// WHERE YOU ISSUE THE COMMANDS
out.println(chatMsg.getText().toString());
Log.d("ClientActivity", "C: Sent.");
} catch (Exception e) {
Log.e("ClientActivity", "S: Error", e);
}
}
}
socket.close();
Log.d("ClientActivity", "C: Closed.");
} catch (Exception e) {
Log.e("ClientActivity", "C: Error", e);
connected = false;
}
}
}
public class ClientThreadListener implements Runnable {
protected Socket serverSocket = null;
protected String mMsgFromServer;
public ClientThreadListener(Socket serverSocket) {
this.serverSocket = serverSocket;
}
public void run() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
serverSocket.getInputStream()));
while ((mMsgFromServer = in.readLine()) != null) {
Log.d("MESSAGE FROM SERVER: ", mMsgFromServer);
handler.post(new Runnable() {
#Override
public void run() {
msgFromOtherClients.append('\n'
+ "Message From Server: " + mMsgFromServer);
}
});
}
} catch (Exception e) {
Log.e("ClientListener", "C: Error", e);
connected = false;
}
}
}
}
Your code has some issue that prevents it from working.
As already said in other answers, in your code you are closing the socket output stream right after sending the message to the client. call close() only out of your for message loop. Of course closing the socket in the client will have the same effect as closing it on the server. You must close the sockets only when client and server have finished talking. Closing it while transmitting data it's like hanging up the phone in the middle of a conversation.
Second, you create a new socket on the client side:
Log.d("ClientActivity", "C: Connecting...");
Socket socket = new Socket(serverAddr, Server.SERVERPORT);
but then you pass to the listener another, newly created, socket (I suppose this is not intended):
connected = true;
Thread listener = new Thread(new ClientThreadListener(new Socket(serverAddr, Server.SERVERPORT)));
listener.start();
Third, always call flush() on an output stream right after sending data, or the data will likely not be sent (the send methods will just enqueue your data in the sending buffer).
Last (This may not be useful to you since I don't know your ultimate goal), if you need to send and receive on sockets, 90% of the time it's better and easier to do this asinchronously, using separate threads for listening and sending.
If it still doesn't work, add here some output or log trace from logcat.
You need to move the line:
server.broadcastMessage(mMsgFromClient);
inside the while:
while ((mMsgFromClient = in.readLine()) != null) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.append('\n'
+ "Message From Client ID " + getID()
+ ": " + mMsgFromClient);
}
});
// HERE
Log.d("SERVERTEXT", "Proceed to broadcast");
server.broadcastMessage(mMsgFromClient);
}
Otherwise, you'll only broadcast null.
EDIT: You should make sure that mMsgFromClient is not changed between posting the new Runnable and it actually executing. The best way is to initialize a field in the anonymous class with the current value, and log the value of that field instead.
EDIT2: Unless your server is supposed to close its connection to a client after sending it a broadcast message, you should use out.flush() instead of out.close() in the broadcastMessage method. It's preferrable that client connections are closed after a timeout, or just let the clients disconnect, again with a timeout.
Otherwise, your test will be very limited most of the times: a client connects and sends a message; then it receives its own message and the server closes the connection.
Please try to use AsyncTask in android which will create separate thread for communication with server.
I had two issues in the program I am making... the thing is that I want to send by a Edittext that information to a server via UDP....the thing is that the program only works the first time I run the program, I mean, if i open the application and write some text, the information is sended to the server, but if I type another thing and press to button so the new information is sended it doesn't work... the other thing is that the TextView is not appending the information, and the server send some info but the application is not gathering that information... so if someone had a clue why is this happening or what I am doing wrong I appreciated any help!... Thanks in advice...
here is the code:
public class MainActivity extends Activity implements View.OnClickListener {
public static final String SERVERIP = "190.99.20.200";
public static final int SERVERPORT = 5153;
public TextView serverResponse;
public EditText messageToSend;
public Button btnSend;
public boolean start;
public Handler handler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
serverResponse = (TextView)findViewById(R.id.textView);
messageToSend = (EditText)findViewById(R.id.editText);
btnSend = (Button)findViewById(R.id.button);
btnSend.setOnClickListener(this);
start = false;
new Thread(new Server()).start();
try{
Thread.sleep(500);
}catch (InterruptedException e){
updatetrack("Error on Server:" + e.getMessage());
}
new Thread(new Client()).start();
handler = new Handler(){
public void handledMessage(Message msg){
String text = (String)msg.obj;
serverResponse.append(text);
}
};
}
public class Client implements Runnable {
#Override
public void run() {
while(start == false)
{
}
try{
Thread.sleep(500);
}catch (InterruptedException e1){
e1.printStackTrace();
}
try{
InetAddress serverAddres = InetAddress.getByName(SERVERIP);
updatetrack("Client:Start connectingn");
DatagramSocket socket = new DatagramSocket();
byte[] buffer;
if(!messageToSend.getText().toString().isEmpty())
{
buffer = messageToSend.getText().toString().getBytes();
}
else
{
buffer = ("Message from android").getBytes();
}
DatagramPacket packet = new DatagramPacket(buffer, buffer.length,serverAddres,SERVERPORT);
updatetrack("Client:Sending" + new String(buffer)+ "'n");
socket.send(packet);
updatetrack("Client: Messange sentn");
updatetrack("Client: Succed!n ");
socket.close();
}catch (Exception e){
updatetrack("Client:Error!n" + e.getMessage());
}
}
}
public class Server implements Runnable{
#Override
public void run() {
while (start == false)
{
}
try{
InetAddress serverAddress = InetAddress.getByName(SERVERIP);
updatetrack("nServer: Start connectingn");
DatagramSocket socket = new DatagramSocket(SERVERPORT, serverAddress);
byte[] buffer = new byte[17];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
updatetrack("Server: Receivingn");
socket.receive(packet);
updatetrack("Server: Message received:" + new String(packet.getData())+"'n");
updatetrack("Server : Succed!n");
}catch (Exception e){
updatetrack("Server: Error!n"+ e.getMessage());
}
}
}
public void onClick(View view)
{
start = true;
}
public void updatetrack(String s)
{
Message msg = new Message();
String textTochange = s;
msg.obj = textTochange;
handler.sendMessage(msg);
}
}
The run method in your server class will run only once.
while(start == false){
}
This while loop will continue to loop until you call the onClick method, at which point the rest of the code in the run() method is executed, and the server thread killed. You need to rearrange your code a little, and place it inside the while loop:
public void run() {
while (true){
try{
InetAddress serverAddress = InetAddress.getByName(SERVERIP);
updatetrack("nServer: Start connectingn");
DatagramSocket socket = new DatagramSocket(SERVERPORT, serverAddress);
byte[] buffer = new byte[17];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
updatetrack("Server: Receivingn");
socket.receive(packet);
updatetrack("Server: Message received:" + new String(packet.getData())+"'n");
updatetrack("Server : Succed!n");
}catch (Exception e){
updatetrack("Server: Error!n"+ e.getMessage());
}
}
}