2017-08-18 4 views
1

Je ces ici méthodes:TcpClient - Comment se connecter correctement, maintenir la connexion et enfin déconnecter

private void connectToServer() { 
     client = new TcpClient(SERVER_IP, PORT_NO); 
     nwStream = client.GetStream(); 

     writer = new StreamWriter(client.GetStream()); 
     writer.AutoFlush = true; 
     connected = true; 

     getDataFromServer(); 
     rtb_inputField.Select(); 

     if (getDataTimer == null) { 
      getDataTimer = new System.Timers.Timer(); 
      getDataTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 
      getDataTimer.Interval = 1000; 
      getDataTimer.Enabled = true; 
     } 
    } 

    private void disconnectFromServer() { 
     if (connected) { 
      writer.WriteLine("quit"); 
      getDataTimer.Enabled = false; 
      getDataTimer.Dispose(); 
      getDataTimer = null; 

      Thread.Sleep(1000);  //Wait 1 second 
      nwStream.Close(); 
      client.Close(); 
      rtb_outputWindow.AppendText("\n\nClient: Disconnected."); 
     } 
     connected = false; 
    } 

    private void getDataFromServer() { 
     if (connected) { 
      new Thread(() => { 
       Thread.CurrentThread.IsBackground = true; 
       byte[] bytesToRead = new byte[client.ReceiveBufferSize]; 
       int readData = nwStream.Read(bytesToRead, 0, client.ReceiveBufferSize); 
       updateOutputWindow(Encoding.Default.GetString(bytesToRead, 0, readData)); 
      }).Start(); 
     } 
    } 

    private void updateOutputWindow(string text) { 
     string newText = string.Empty; 

     if (InvokeRequired) { 
      Invoke(new MethodInvoker(delegate() { 
       updateOutputWindow(text); 
      })); 
     } 
     else { 
      newText = startRTFString; 
      newText += rtb_outputWindow.Rtf; 
      newText += replaceAnsiColorCodes(text); 

      rtb_outputWindow.Rtf = newText; 
     } 
    } 

    private void OnTimedEvent(object source, ElapsedEventArgs e) { 
     if (connected) { 
      getDataFromServer(); 
     } 
    } 

tout cela fonctionne, mais quelque chose qui ne va pas. Quand je déconnecte le outputWindow obtient beaucoup de nouvelles lignes avant de dire finalement "Client: Déconnecté." Plus je reste connecté au serveur, plus la déconnexion est longue. Je crois que la minuterie a quelque chose à voir avec ce problème. Le travail de la minuterie consiste à demander en continu des données au serveur et à les sortir si l'un d'entre eux est reçu. Y a-t-il une meilleure façon de le faire? Peut-être "attendez que le serveur envoie des données" - dans le cas où rien ne sera envoyé pendant plusieurs secondes, je n'aurai pas à marteler le serveur pour les demandes.

Le nouveau thread de la méthode getDataFromServer est-il pris en charge par le garbage collector? Ou dois-je en disposer d'une manière ou d'une autre? (Pour ne pas créer tout un tas de threads d'arrière-plan.)

+0

Voici un autre exemple simple https://stackoverflow.com/questions/21510204/c-sharp-tcpclient-send-serialized-objects -using-separators –

Répondre

0

Vous n'avez pas besoin d'une minuterie pour écouter les données entrantes. Cela devrait être géré automatiquement pour vous. Chaque fois que la tâche du fil d'écoute est appelée, elle doit recevoir toutes les données entrantes, puis terminer la tâche afin que les autres threads puissent s'exécuter.

Ici, j'ai un échantillon d'une tâche d'écoute d'un de mes projets. Les données entrantes sont des chaînes sérialisées.

void ListeningObjectTask()// Recieves any data sent by the other user. 
     { 
      while (client != null && client.Connected)// If there is another user and they are connected. 
      { 
       try// This suppresses exceptions thrown by connection problems, such as the user losing network signal. 
       { 
        recieve = str.ReadLine();// Gets the data sent by the other user. 
        if (recieve != "")// If the user has sent data. 
        { 
         lock (recievedStrings)// Locks the buffer to add the data sent by the other user to it. 
         { 
          recievedStrings.Enqueue(recieve); 
         } 
         recieve = "";// Clears the incoming data, as it has been stored. 
        } 
       } 
       catch (Exception Ex) 
       { 
        // Ends all the other multiplayer objects as the connection has ended and they are no longer needed. 
        Disconnect(); 
        // Tells the user why they have lost connection, so that they can try to fix the problem. 
        MessageBox.Show("Network connection ended\n" + Ex); 
       } 
      } 
     } 

Voici les déclarations des objets utilisés:

private TcpClient client;// Allows connections for tcp network services. 
private StreamReader str; // Provides an interface to read from a stream. 
private string recieve;// The incoming string recieved from the other user. 
readonly Queue<string> recievedStrings = new Queue<string>();// A buffer to hold incoming data from the other user. 
+0

Comment connecter tout cela à ce que j'ai actuellement? Ai-je besoin d'un TCPListener? –

+2

Ce n'est pas vraiment l'endroit pour moi de poster un tutoriel sur C# sockets. Si vous avez un problème très spécifique, vous pouvez m'envoyer un email (qui est sur ma page de profil). – 0liveradam8