2009-04-27 16 views
0

Ich benutze Visual Studio, um diesen kleinen TcpServer zu programmieren.Programm hängt, wartet auf Eingabe, die ich nie geben kann

Es ist wirklich spezifisch. Der Server hört Port 1234 ab und befindet sich unter IP 127.0.0.1 Unsere Lehrer haben uns ein Programm zur Verfügung gestellt, das versucht, sich mit dem Port dieser IP zu verbinden, wenn Sie auf "Verbinden" klicken. Es funktioniert für alle anderen, daher muss es ein Codierungsfehler sein.

Wenn ich auf connect klicke, sendet das Programm das Wort "GET" über den Stream, auf den ich mit einer Liste von bereits verbundenen IP-Adressen antworten muss und dann einen Zeilenumbruch, der nur einen enthält.

Wenn ich trennen, das Programm, das Wort „REM“ sendet und ich muss einfach, wenn aus meiner Liste entfernen (die eine allgemeine Liste ist)

ich eine Klasse TCPServer haben (wir hatten unseren eigenen zu machen) was hat dies als Hauptcode:

this.tl = new TcpListener(IPAddress.Any, PORT); 
tl.Start(); 
while(true) 
{ 
    TcpClient tcl = tl.AcceptTcpClient();//here the server will wait forever untill someone connects, meaning the "new Thread" statement is never reached untill someone connects. 
    TcpHelper th = new TcpHelper(tcl,conf); 
    new Thread(new ThreadStart(th.Start)).Start();//should be multi-threaded, not sure if it is. 
    //t.Start(); 
} 

TcpHelper sieht wie folgt aus (suchen Sie nach dem kommentierten Text „hier ist das Problem“ innerhalb der usings):

public class TcpHelper 
{ 
    private TcpClient tc; 
    private IPEndPoint ipe; 
    private string get; 
    private Configuration conf; 

    public TcpHelper(TcpClient tc, Configuration conf) 
    { 
     this.tc = tc; 
     this.conf = conf; 
    } 

    public void Start() 
    { 
     using (NetworkStream nws = this.tc.GetStream()) 
     { 
      using (StreamReader sr = new StreamReader(nws)) 
      { 
       using (StreamWriter sw = new StreamWriter(nws)) 
       { 
        this.ipe = (IPEndPoint)tc.Client.RemoteEndPoint; 
        this.conf.List.Add(this.ipe.Address); 
        bool conn = true; 

        while (conn) 
        { 
         this.get = sr.ReadLine();//here's the problem 
         switch (this.get) 
         { 
          case "GET": 
           foreach (IPAddress address in this.conf.Lijst) 
           { 
            sw.WriteLine(address.ToString()); 
           } 
           sw.WriteLine("."); 
           break; 

          case "REM": 
           this.conf.List.Remove(this.ipe.Address); 
           sw.WriteLine("OK."); 
           conn = false; 
           break; 

          default: 
           break; 
        } 
        } 
       } 
      } 
     } 
    } 

    #region Properties 
    public IPEndPoint Ipe 
    { 
     get 
     { 
      return this.ipe; 
     } 
    } 
    #endregion 
} 
+1

Sie können mithilfe von Anweisungen übereinander stapeln; Sie müssen Klammern nicht wie Nüsse nisten. – Will

+0

Ich weiß, ich finde das optisch ansprechend. – KdgDev

Antwort

0

Sorry, vielleicht verstehe ich das nicht ... Hast du diesen Code geschrieben?

this.tl = new TcpListener(IPAddress.Any, PORT); 
tl.Start(); 
while(true) 
{ 
    TcpClient tcl = tl.AcceptTcpClient(); 
    TcpHelper th = new TcpHelper(tcl,conf); 
    new Thread(new ThreadStart(th.Start)).Start(); 
    //t.Start(); 
} 

Dies wird den **** aus jedem Computer blasen. Sie schleifen endlos und erstellen neue Threads in jeder Schleife. Wenn Sie also einen neuen Thread pro Schleife erstellen und jede Schleife eine Millisekunde dauert (sagen wir, sie ist sehr langsam!), Haben Sie in fünf Sekunden 5.000 Threads. Jeder versucht, am selben Port zu hören.

Verwenden Sie einen einzelnen Thread. Wenn es sich um eine Konsolenanwendung handelt, verwenden Sie Console.ReadLine(), um den Hauptthread zu blockieren, bis jemand die Eingabetaste drückt.


Mit den neuen Informationen ... AcceptTcpClient Blöcke, sondern einem neuen Thread, um die Arbeit zu schaffen, sollte auf dem Threadpool der Warteschlange gestellt werden.

+0

Ja, das habe ich geschrieben. Aber bedenkt das. 1) Es muss für immer Schleife, weil es ein Server ist. Sie schalten den Server nicht herunter. 2) Die Schleife wird nicht fortgesetzt, da der "tl.AcceptClient();" bit wartet auf eine Verbindung und zwingt das Programm zu warten. Keine neuen Threads, bis sich jemand verbindet. – KdgDev

+0

Okay, also ist es nicht so schlimm. Trotzdem erstellen Sie bei jeder Verbindung einen neuen Thread. Das ist nicht gut. Stellen Sie diese auf den ThreadPool, der Threads für Sie verwaltet und wiederverwendet. – Will

+0

ThreadPool Sie sagen? Ich habe meine Kurse überprüft und es wird nie erwähnt. Ich werde mich darum kümmern und mit den Programmierlehrern nachsehen. Ich fragte mich, wie ich verfolgen könnte, welcher Thread was macht. Ich hoffe, das macht das für mich. – KdgDev

6

Meine Vermutung ist, dass Ihr Problem ist, dass Sie rufen sr.ReadLine() auf, aber die Eingabe enthält keinen Zeilenumbruch, so dass sie dort blockiert ist und auf einen Zeilenumbruch wartet, der nie kommen wird.

möchten Sie vielleicht versuchen, StreamReader.Read 3 mal aufzurufen, um die Befehlszeichenfolge (GET/REM) aufzubauen, bevor Sie darauf reagieren. (Hinweis: 3-mal ist, weil alle Befehle drei Zeichen sind).

Lesen wird Ganzzahlen zurückgeben, aber nachdem Sie überprüft haben, dass sie nicht -1 (Angabe des Dateiendes) sind, können Sie diese ganze Zahl in ein Zeichen umwandeln.

+0

Huh ..? Drei Mal? Hört sich für mich nach einer zweifelhaften Idee an? Sie sollten weiter lesen, bis Sie haben, was Sie wollten, vorausgesetzt, das Protokoll diktiert eine neue Zeile, scheint ReadLine wie eine perfekte Passform. – falstro

+0

ooooh, ich sehe, lesen Sie ein Zeichen nach dem anderen ... – falstro

+0

Die Sache ist, liest eine Ganzzahl zurück ... was gut tut mir das ... – KdgDev

Verwandte Themen