2017-08-11 4 views
0

J'essaie maintenant de faire un client simple (en utilisant Windows.Forms) qui se connecte à un serveur Telnet, et qui est capable d'envoyer et de recevoir des données.Telnet Server: envoyer et recevoir des données

J'ai réussi à me connecter au serveur, mais je n'arrive pas à comprendre comment renvoyer les données au serveur. (Après que je dois savoir comment recevoir les données de réponse, mais je ne l'ai pas fait jusque-là encore.)

Voici mon code actuel:

using System; 
using System.Net.Sockets; 
using System.Text; 
using System.Threading; 
using System.Windows.Forms; 

namespace MUDClient { 
public partial class Form1 : Form { 
    const string SERVER_IP = "166.78.5.182"; 
    const int PORT_NO = 9999; 
    NetworkStream nwStream; 
    TcpClient client; 

    public Form1() { 
     InitializeComponent(); 
    } 

    private void btn_connect_Click(object sender, EventArgs e) { 
     connectToServer(); 
    } 

    private void btn_disconnect_Click(object sender, EventArgs e) { 
     client.Close(); 
     nwStream.Close(); 
     rtb_outputWindow.AppendText("\n\nClient: Disconnected."); 
    } 

    private void outputWindowTextChanged(object sender, EventArgs e) { 
     rtb_outputWindow.SelectionStart = rtb_outputWindow.Text.Length; 
     rtb_outputWindow.ScrollToCaret(); 
    } 

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

     new Thread(() => { 
      Thread.CurrentThread.IsBackground = true; 
      while (client.Connected) { 
       byte[] bytesToRead = new byte[client.ReceiveBufferSize]; 
       int bytesRead = nwStream.Read(bytesToRead, 0, client.ReceiveBufferSize); 
       updateOutputWindow(Encoding.ASCII.GetString(bytesToRead, 0, bytesRead)); 
      } 
     }).Start(); 
    } 

    private void updateOutputWindow(string text) { 
     if (InvokeRequired) { 
      Invoke(new MethodInvoker(delegate() { 
       updateOutputWindow(text); 
      })); 
     } 
     else { 
      rtb_outputWindow.AppendText(text); 
     } 
    } 

    private void userSentInput(object sender, KeyEventArgs e) { 
     RichTextBox inputField = (RichTextBox)sender; 
     string userInput = inputField.Text.Trim(); 

     if ((e.KeyData == Keys.Enter) && (sender == rtb_inputField)) { 
      if (nwStream != null) { 
       if (!string.IsNullOrWhiteSpace(userInput)) { 
        byte[] bytesToSend = Encoding.ASCII.GetBytes(userInput); 

        nwStream.Write(bytesToSend, 0, bytesToSend.Length); 
        nwStream.Flush(); 

        rtb_inputField.Clear(); 
        rtb_inputField.Update(); 
       } 
      } 
     } 
    } 
} 
} 

Mon programme a deux RichTextBoxes (un pour l'entrée de l'utilisateur et un pour "sortie du serveur" aka données reçues), et deux boutons (connecter et déconnecter).

Cliquez sur le bouton Connecter pour exécuter la méthode connectToServer() qui ouvre une connexion entre le serveur et le client.

Pour envoyer des données que je veux taper dans le RichTextBox (rtb_inputField), et lorsque l'utilisateur appuie sur Entrée, les données sont envoyées. C'est la partie qui ne fonctionne pas. Rien ne semble arriver quand j'appuie sur Entrée.

EDIT: J'ai mis à jour le code. J'ai ajouté une boucle de connexion continue dans un nouveau thread. Cela fonctionne parce que je peux voir l'écran de bienvenue du serveur. Cependant, je ne peux toujours rien envoyer au serveur. Et si je clique sur le bouton Déconnecter le programme se bloque avec l'exception "Une exception non gérée de type 'System.IO.IOException'" dans la boucle continue.

Répondre

0

Essayez le rinçage du flux après l'écriture:

nwStream.Flush() 

Vous aurez également besoin de lire péremptoire en enveloppant la lecture dans une boucle

while (client.Connected) 
{ 
    byte[] bytesToRead = new byte[client.ReceiveBufferSize]; 
    int bytesRead = s.Read(bytesToRead, 0, client.ReceiveBufferSize); 
    Console.Write(Encoding.ASCII.GetString(bytesToRead, 0, bytesRead)); 
} 
+0

Qu'est-ce videra faire? Comment lire en continu? –

+0

flush videra vers le périphérique de soulignement comme ils seront un peu de tampon dans le chemin, aussi juste envelopper la lecture dans une boucle –

+0

J'ai ajouté la boucle à ma méthode connectToServer. Lorsque j'ai cliqué sur le bouton Connecter, le programme a été «retardé» (il ne s'est pas crashé, mais il n'a pas répondu non plus). Peut-être qu'il communique trop souvent avec le serveur? Dois-je mettre cette chose dans une minuterie et le faire une fois par seconde? –