Acceder

Ver la Versión Completa : [ CONSULTA ] Conexión servidor-cliente bidireccional


autodrc
28/03/16, 17:12:30
Buenas tardes,

Estoy intentando realizar una conexión servidor-cliente bidireccional con Android Studio pero no hay manera de que el cliente reciba los datos del servidor. La conexión se hace bien y puedo enviar mensajes desde el cliente al servidor y visualizarlos en el servidor sin problema, pero al contrario estoy teniendo problemas.

A ver si me podéis echar una mano!

Gracias

Este es mi código hasta el momento:

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public class SettingsActivity extends AppCompatActivity implements OnClickListener {
EditText etMessage, ipadress, ipport;
Button bSend;
TextView msgrec;

override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
etMessage = (EditText) findViewById(R.id.welcomeMsg);
bSend = (Button) findViewById(R.id.checkconnection);
ipadress = (EditText) findViewById(R.id.ipadress);
ipport = (EditText) findViewById(R.id.ipport);
msgrec = (TextView) findViewById(R.id.msgrec);

bSend.setOnClickListener(this);
}

override
public void onClick(View v) {
Thread t = new Thread() {

override
public void run() {
String dstAddress;
int dstPort;
String datoport;
String response;
String msgToServer;

try {
msgToServer = etMessage.getText().toString();
dstAddress = ipadress.getText().toString();
datoport = ipport.getText().toString();
dstPort = Integer.parseInt(datoport);

Socket socket = new Socket(dstAddress, dstPort);
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());

dos.writeUTF(msgToServer);

socket = new Socket(dstAddress, dstPort);
DataInputStream dis = new DataInputStream(socket.getInputStream());
response = dis.readUTF();
msgrec.setText(response);
dis.close();

dos.flush();
dos.close();
socket.close();

} catch (IOException e) {
e.printStackTrace();
}
}
};
t.start();
}
}

mocelet
28/03/16, 17:43:20
Tienes una errata, supongo que de hacer copy-paste, abres el socket dos veces. Después de dos.writeUTF abres otro socket (borra ese segundo socket = new Socket...), así que lo que se supone que ibas a leer no está porque es otra conexión.

autodrc
28/03/16, 18:32:09
Lo he arreglado pero sigue sin funcionar... he probado varias estructuras y no hay manera... gracias de todas formas mocelet.

mocelet
28/03/16, 18:54:17
Entonces fallará otra cosa :) Resolver los fallos consiste en eso, en ir tirando del hilo.

¿El servidor es Java? ¿Escribes los datos también con writeUTF?

kriogeN
28/03/16, 22:21:47
Si lo que quieres es que por cada mensaje que envías al servidor tengas una respuesta del cliente tu código es correcto. Ya que se ejecutan en secuencia.

Ahora bien, si quieres poder enviar y recibir datos en cualquier momento, independientemente de lo que ya hayas enviado o recibido, deberás poner los sockets en hilos distintos.

autodrc
28/03/16, 22:54:36
Perdonarme, soy nuevo en esto de java y android. El servidor no es java y la idea es poder recibir un mensaje del servidor en cualquier momento así que tendré que hacer lo que tu dices, por un lado enviar datos y por el otro recibirlos. Gracias! a ver si me las apaño pronto.

mocelet
29/03/16, 00:22:05
Cosas varias entonces:
- No uses readUTF ni writeUTF. Esos están hechos para leer con uno lo que escribes con el otro (añaden información de cuántos bytes hay que leer, si el servidor no sigue la misma convención no funcionará como se espera, que es lo que probablemente te ocurre). En su lugar usa read o write a nivel de bytes, o alguno de los Reader/Writer de Java que te facilita el trabajo con cadenas de caracteres.
- Como te apuntaba kriogeN, si quieres leer todo el rato necesitas otro hilo más que, en bucle, se dedique a leer del input stream. Además del hilo que se dedica a escribir.
- A lo mejor te compensa buscar alguna biblioteca que facilite un poco el trabajo y esté orientada a mensajes y no tanto a la conexión. Aunque para aprender siempre es mejor pelearse con el socket y saber qué ocurre por debajo.

EDIT: Ejemplos de bibliotecas de mensajería ligeras: zeroMQ (http://zeromq.org) (que tiene cliente nativo Java jeromq (https://github.com/zeromq/jeromq)), mosquitto (http://mosquitto.org). Para el tema de comunicarse con microcontroladores igual son más apropiados por su orientación a mensajes y permitir patrones de publicación / suscripción además de reconexión automática o envío de mensajes encolados. Ya depende del caso de uso concreto, pero con estas bilbiotecas no tienes que saber qué es un socket ni molestarte en codificar ni en encapsular datos, simplemente envías mensajes y recibes mensajes.