2011-06-15 662 views
5

Estoy escribiendo una aplicación de cliente que recibirá un flujo continuo de datos a través de tcp/ip. El problema que estoy teniendo es que el objeto del lector almacenado no está recibiendo ningún dato y está colgando en el método readline.lector de búfer que no recibe datos del socket

La manera en que funciona el servidor es que se conecta a ella y luego envía información de autenticación para recibir datos. La esencia de mi código está por debajo

socket = new Socket(strHost, port); 
authenticate(); 
inStream = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
process(inStream); 

authenticate() 
{  
    PrintWriter pwriter = new PrintWriter(socket.getOutputStream(), true); 
    pwriter.println(authString); 
} 

process(BufferedReader bufferedReader) 
{ 
    while((line = bufferedReader.readLine()) != null) 
     dostuff 
} 

He creado una aplicación de servidor que envía los datos de la muestra del camino (creo) el servidor está enviando datos y se conecta y recibe y procesa la multa datos. Me puedo conectar al servidor bien en mi aplicación. También puedo hacer una telnet en el servidor y escribir la cadena de autenticación y recibir una gran cantidad de datos usando telnet. Sin embargo, mi aplicación simplemente se cuelga en readLine con el servidor y estoy fuera de la idea de por qué.

Los datos que entran (a través de al menos telnet) se parece a un flujo continuo de los siguientes:

data;data;data;data;data 
data;data;data;data;data 

¿Por qué mi aplicación colgando en readline, no estoy dando salida a la línea de autenticación correctamente? No recibo ningún error ...

EDITAR Mi código de servidor de ejemplo (que está funcionando correctamente) ... otra vez esto sólo está imitando la forma Creo el servidor real se está ejecutando, pero Puedo conectarme a ambos en mi aplicación simplemente no recibir datos del servidor real.

public static void main(String[] args) throws IOException 
    { 
    ServerSocket serverSocket = null; 

    try 
    { 
    serverSocket = new ServerSocket(1987); 
    } 
    catch (IOException e) 
    { 
    System.out.println("Couldn't listen on port: 1987"); 
    System.exit(-1); 
    } 

    Socket clientSocket = null; 
    try 
    { 
    clientSocket = serverSocket.accept(); 
    } 
    catch (IOException e) { 
    System.out.println("Accept failed: 1987"); 
    System.exit(-1); 
    } 

    PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); 
    BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
    String something; 

    while ((something = in.readLine()) != null) 
    { 
    while(true) 
    { 
     out.println(message); 
    } 
    } 



    out.close(); 
    in.close(); 
    clientSocket.close(); 
    serverSocket.close(); 
} 
+0

nos el código del servidor relacionado con el problema puede mostrar? – Coeffect

+0

'Me puedo conectar bien al servidor en mi aplicación. ¿Te refieres a tu servidor de muestra ficticio? – leonbloy

+0

Quizás debería tener otro hilo listo para leer sus datos _antes de que envíe la autenticación? Supongo que el servidor simplemente comienza a inundar los datos tan pronto como recibe la contraseña. – toto2

Respuesta

10

En primer lugar debe llamar a BufferedReader.ready() antes de llamar readLine(), como el ready() le dirá si está bien para leer.

PrintWriter no emite Excepción de E/S por lo que la escritura puede haber fallado sin su conocimiento, por lo que no hay nada que leer. Use PrintWriter.checkError() para ver si algo salió mal durante la escritura.

Debe configurar los flujos de entrada y salida en el Socket al mismo tiempo antes de escribir algo en la tubería. Si su lector no está listo cuando el otro extremo intenta escribir, obtendrá un conducto roto en el servidor y no enviará más datos. Telnet configura leer y escribir antes de haber escrito o leído algo.

Puede hacer uso de Wireshark para saber si el servidor realmente está enviando datos.

+1

bufferedreader.ready parecía hacer el truco, gracias por la sugerencia en printwriter.checkerror y estoy agregando eso a mi código. – Ryan

+0

@DavidNewcomb ¿Por qué debería configurar, por ejemplo, un BufferedReader desde un InputStream de un socket antes de enviar algo? ¿Realmente come datos que llegan de antemano? ¿Cómo funciona esto con las fuentes de datos que siempre tienen datos iniciales disponibles? - Esperaría que cualquier contenedor de Stream fuera a buscar, pero ¿no comiera datos iniciales? –

+1

Con BufferedXxx no puede decir cuándo se realizarán realmente las lecturas o escrituras. El canal de comunicaciones es una tubería y las tuberías deben tener lectores y escritores trabajando juntos. No consume datos, se obtiene un conducto roto si intentas escribir algo y no hay nada que leer, de la misma forma que tu lectura se bloqueará si nadie está escribiendo en el otro extremo. –

8

BufferdReader.readLine() lee las líneas, es decir, las secuencias de caracteres terminaron en \r o \r\n. Supongo que su servidor escribe su salida en una sola línea. Su salida de telnet demuestra esta suposición. Solo use PrintWriter.println() en el lado del servidor.

+1

O tendrá que usar 'leer (char [] cbuf, int off, int len) 'si se trata de una transmisión continua larga. – toto2

-1

este trabajo conmigo con toma sin rubor

void start_listen() 
    { 
     String result1=""; 
     char[] incoming = new char[1024]; 
     while (!s.isClosed()) 
     { 
      try { 

      int lenght = input.read(incoming); 
       result1 = String.copyValueOf(incoming,0,lenght); 


      } 
      catch (IOException e) 
      { 
       e.printStackTrace(); 
      } 
      Log.d("ddddddddddd",result1); 

     } 
Cuestiones relacionadas