2009-12-03 11 views
6

J'essaie toujours d'améliorer un peu ce que j'ai écrit auparavant. Maintenant, j'ai eu un problème avec la réception de données. J'ai un programme que j'utilise pour envoyer une chaîne en utilisant tcpClient à un programme dans lequel j'écoute sur un port spécifié. Il fonctionne très bien alors j'ai décidé d'envoyer des données vers l'avant une fois de plusRecevoir et envoyer des données 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(); 
    } 
} 

Parfois, il fonctionne très bien, mais le plus souvent, permet d'appeler un récepteur, ne peut pas obtenir ce que Im essayant d'envoyer. Et je ne sais vraiment pas ce qui ne va pas. On dirait qu'il peut y avoir un problème avec la méthode d'envoi. Voici un exemple de sortie de récepteurs

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... 

Répondre

1

Assurez-vous que les données existent réellement sur le flux avant de poursuivre les fantômes. S'il y a TOUJOURS des données, nous pouvons aborder le problème, mais en le regardant logiquement, il semble que le flux soit annulé ou qu'il n'y ait aucune donnée.

+0

On peut dire qu'elle dépend de la vitesse des données est arrivée et non chacun de celui-ci peut être envoyé si la majeure partie est perdue. Votre réponse m'a amené à penser plus à ce sujet:> – Allek

6

Plusieurs problèmes ici:

  1. StreamReader a un tampon et 4Ko essaiera de lire autant que possible dans le premier appel à ReadLine(). Le résultat est que vous pourriez avoir des données dans StreamReader et aller dans Poll() quand il n'y a plus de données disponibles parce qu'il a déjà été lu.
  2. Poll() prend des microsecondes. En attente 0,02ms pour les données entrantes est susceptible de renvoyer faux sauf si les données sont là avant d'appeler Poll().
  3. Vous créez un StreamReader à chaque itération, ce qui peut annuler les données déjà lues dans le précédent.

Si vous allez juste lire les lignes et que vous voulez un délai d'attente et un StreamReader, je ferais quelque chose comme:

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

Je ne sais pas encore ce qui se passe ici. Je ne suis pas bon dans ce que je voudrais être. Pouvez-vous expliquer un peu plus à ce sujet? et existe-t-il une autre et meilleure option pour recevoir ces données et les envoyer sans utiliser StreamReader ?? C'est ma première tentative d'écrire quelque chose comme ça donc je ne suis pas sûr de ce qui est meilleur ou pire – Allek

+0

Ce que fait le code ci-dessus est de lire les lignes jusqu'à ce que le flux soit fermé du côté serveur ou jusqu'à plus de 100 ms. Comme pour les autres options de lecture/écriture, cela dépend de ce que vous voulez faire. L'interface "naturelle" est d'utiliser byte [] avec Socket. – Gonzalo

Questions connexes