2009-12-03 22 views
6

Im tratando de mejorar un poco lo que escribí antes. Ahora me enfrenté a un problema con la recepción de datos. Tengo un programa que utilizo para enviar cadenas usando tcpClient a un programa en el que estoy escuchando en un puerto específico. Trabaja muy bien, así que decidí enviar datos hacia adelante una vez másRecepcion y envío de datos en C#

public static void receiveThread() 
{ 
    while (true) 
    { 
     TcpListener tcpListener = new TcpListener(IPAddress.Any, port); 
     tcpListener.Start(); 

     Console.WriteLine("Waiting for connection..."); 

     TcpClient tcpClient = tcpListener.AcceptTcpClient(); 

     Console.WriteLine("Connected with {0}", tcpClient.Client.RemoteEndPoint); 

     while (!(tcpClient.Client.Poll(20, SelectMode.SelectRead))) 
     { 
      NetworkStream networkStream = tcpClient.GetStream(); 
      StreamReader streamReader = new StreamReader(networkStream); 

      data = streamReader.ReadLine(); 

      if (data != null) 
      { 
       Console.WriteLine("Received data: {0}", data); 
       send(data); // Here Im using send Method 
      } 
     } 
     Console.WriteLine("Dissconnected...\n"); 
     tcpListener.Stop(); 
    } 
} 

/// <summary> 
/// Sending data 
/// </summary> 
/// <param name="data">Data to send</param> 
public static void send(string data) 
{ 
    TcpClient tcpClient = new TcpClient(); 
    try 
    { 
     tcpClient.Connect(ipAddress, sendPort); 
     Console.WriteLine("Connected with {0}", tcpClient.Client.RemoteEndPoint); 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e); 
    } 
    if (tcpClient.Connected) 
    { 
     NetworkStream networkStream = tcpClient.GetStream(); 
     StreamWriter streamWriter = new StreamWriter(networkStream); 
     Console.WriteLine("Messege {0} to {1}", data, tcpClient.Client.RemoteEndPoint); 
     streamWriter.WriteLine(data); 
     streamWriter.Flush(); 
     tcpClient.Close(); 
    } 
} 

veces funciona bien, pero más a menudo, permite llamar a un receptor, no puede conseguir lo que estoy tratando de enviar. Y realmente no entiendo qué está mal con eso. Parece que puede haber un problema con el método de envío. Aquí hay un ejemplo de receptores

Waiting for connection... 
Connected with 127.0.0.1:52449 
Dissconnected... 

Waiting for connection... 
Connected with 127.0.0.1:52450 
Received data: qweqwe 
Dissconnected... 

Waiting for connection... 
Connected with 127.0.0.1:52451 
Dissconnected... 

Waiting for connection... 
Connected with 127.0.0.1:52452 
Dissconnected... 

Waiting for connection... 
Connected with 127.0.0.1:52453 
Received data: zxczx 
Dissconnected... 

Waiting for connection... 
Connected with 127.0.0.1:52454 
Dissconnected... 

Waiting for connection... 
Connected with 127.0.0.1:52455 
Received data: aasd 
Dissconnected... 

Waiting for connection... 
Connected with 127.0.0.1:52457 
Received data: www 
Dissconnected... 

Respuesta

1

Asegúrese de que los datos realmente existan en la transmisión antes de perseguir fantasmas. Si hay SIEMPRE datos, podemos abordar el problema, sin embargo, mirándolo lógicamente, parece que la secuencia está anulada o simplemente no hay datos en ella.

+0

parece que depende de la rapidez con que los datos son entrante y no cada una de ella se puede enviar así que la mayor parte se pierde. Tu respuesta me hizo pensar más cuidadosamente sobre eso:> – Allek

6

varios problemas aquí:

  1. StreamReader tiene un buffer 4kB y tratará de leer tanto como sea posible en la primera llamada a ReadLine(). El resultado es que puede tener datos en StreamReader y entrar en Poll() cuando ya no hay más datos disponibles porque ya se han leído.
  2. Poll() lleva microsegundos. Esperando 0.02ms para los datos entrantes es probable que devuelva falso a menos que los datos estén allí antes de llamar al Poll().
  3. Crea un nuevo StreamReader en cada iteración, que puede descartar datos ya leídos en el anterior.

Si sólo va a leer las líneas y desea un tiempo de espera y una StreamReader, me gustaría hacer algo como:

delegate string ReadLineDelegate(); 
... 
using (NetworkStream networkStream = tcpClient.GetStream()) { 
    StreamReader reader = new StreamReader(networkStream); 
    ReadLineDelegate rl = new ReadLineDelegate (reader.ReadLine); 
    while (true) { 
     IAsyncResult ares = rl.BeginInvoke (null, null); 
     if (ares.AsyncWaitHandle.WaitOne (100) == false) 
      break; // stop after waiting 100ms 
     string str = rl.EndInvoke (ares); 
     if (str != null) { 
      Console.WriteLine ("Received: {0}", str); 
      send (str); 
     } 
    } 
} 
+0

Aún no sé qué está pasando aquí. No soy tan bueno como me gustaría. ¿Puedes explicar un poco más sobre esto? y ¿hay alguna otra mejor opción para recibir esos datos y enviarlos hacia adelante sin usar StreamReader? Es mi primer intento de escribir algo así, así que no estoy seguro de qué es mejor o peor – Allek

+0

Lo que hace el código anterior es leer líneas hasta que la secuencia se cierra desde el servidor o hasta que se necesita más de 100ms para leer una. En cuanto a otras opciones para leer/escribir, depende de lo que quieras hacer. La interfaz "natural" es usar byte [] con Socket. – Gonzalo

Cuestiones relacionadas