Comunicación de socket entre dos aplicaciones en Android
Tengo un gran problema con mi aplicación de Android y me gustaría pedirle ayuda.
Actualmente estoy escribiendo la aplicación Android Clietn-Server usando sockets. He encontrado muchos tutoriales en Internet y a partir de ellos he creado elementos básicos para mi proyecto. Sin embargo, todos los tutoriales son solo para enviar un mensaje y eso es todo. Necesito enviar más de ellos, así que he estado intentando modificarlo.
Estos son fragmentos de código responsables del servidor y del cliente. El resto no es importante en este momento.
Servidor:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
serverStatus = (TextView) findViewById(R.id.server_status);
recivedMsg = (TextView)findViewById(R.id.rec_msg);
SERVERIP = getLocalIpAddress();
Thread fst = new Thread(new ServerThread());
fst.start();
}
public class ServerThread implements Runnable {
public void run() {
try {
if (SERVERIP != null) {
handler.post(new Runnable() {
@Override
public void run() {
serverStatus.setText("Listening on IP: " + SERVERIP);
}
});
serverSocket = new ServerSocket(SERVERPORT);
while (true) {
// listen for incoming clients
Socket client = serverSocket.accept();
handler.post(new Runnable() {
@Override
public void run() {
serverStatus.setText("Connected." + System.getProperty("line.separator"));
}
});
try {
line = null;
while (connected) {
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
if((line = in.readLine())!=null)
{
Log.d("ServerActivity", line);
handler.post(new Runnable() {
@Override
public void run() {
if(recivedMsg.equals("CLOSE"))
{
recivedMsg.append("CLOSE socket");
connected = false;
}
else
{
recivedMsg.append("MSG: " + line + System.getProperty("line.separator"));
}
// do whatever you want to the front end
// this is where you can be creative
}
});
}
else
{
recivedMsg.append("empty" + System.getProperty("line.separator"));
}
}
break;
} catch (Exception e) {
handler.post(new Runnable() {
@Override
public void run() {
serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones.");
}
});
e.printStackTrace();
}
}
} else {
handler.post(new Runnable() {
@Override
public void run() {
serverStatus.setText("Couldn't detect internet connection.");
}
});
}
} catch (Exception e) {
handler.post(new Runnable() {
@Override
public void run() {
serverStatus.setText("Error");
}
});
e.printStackTrace();
}
}
}
Cliente
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
serverIp = (EditText) findViewById(R.id.server_ip);
connectPhones = (Button) findViewById(R.id.connect_phones);
sendField = (EditText) findViewById(R.id.send_field);
sendMsg = (Button) findViewById(R.id.msg_send);
connectPhones.setOnClickListener(connectListener);
sendMsg.setOnClickListener(sendMessage);
}
@Override
protected void onStop() {
super.onStop();
try {
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//send output msg
String outMsg = "CLOSE";
out.write(outMsg);
out.flush();
// make sure you close the socket upon exiting
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private OnClickListener connectListener = new OnClickListener() {
@Override
public void onClick(View v) {
serverIpAddress = serverIp.getText().toString();
runTcpConnection();
sendMessageToServer("Msg");
}
};
private OnClickListener sendMessage = new OnClickListener() {
@Override
public void onClick(View v) {
sendMessageToServer(sendField.getText().toString());
}
};
private void runTcpConnection() {
try {
s = new Socket(serverIpAddress, SERVERPORT);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//send output msg
String outMsg = "TCP connecting to " + SERVERPORT + System.getProperty("line.separator");
out.write(outMsg);
out.flush();
Log.i("TcpClient", "sent: " + outMsg);
SystemClock.sleep(10);
s.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
};
public void sendMessageToServer(String str) {
try {
s = new Socket(serverIpAddress, SERVERPORT);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//send output msg
String outMsg = str + System.getProperty("line.separator");
out.write(outMsg);
out.flush();
Log.i("TcpClient", "sent: " + outMsg);
s.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("", "hello222");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("", "hello4333");
}
}
Por ahora los dispositivos se conectan correctamente. Además están enviando los primeros mensajes de conexión (aquellos enOnClickListener connectListener
).El problema es que cuando intento enviar otro mensaje usandosendMessageToServer
Es imposible. Esos mensajes se muestran solo después de que se destruye la actividad del cliente.
Muy interesante es que sinSystemClock.sleep(10);
oyenterunTcpConnection()
comportarse extraño Sólo 'Conectado'. muestra en el servidor.
¿Alguien puede decirme qué debo hacer para poder enviar mensajes normalmente?
EDITAR: Estas son cosas que he encontrado:
Si estoy en la conexión, estoy enviando más mensajes que todos los que están vacíos (nulos) y después de que se muestre el segundo error de conexión, vuelva a conectar los teléfonos.Si estoy en la conexión, estoy enviando más mensajes sin cerrar la línea ensendMessageToServer
solo un mensaje esta pasando No se muestra ningún error después de él.El formulario de mensajerunTcpConnection
muestra siempre (excepto cuando en esta función no hay SystemClock.sleep (10))Espero que ayude a alguien a diagnosticar mi error.