2009-04-27 5 views
0

私はVisual Studioを使ってこの小さなTcpServerをプログラムしています。プログラムがハングし、決して与えられない入力を待っています

本当に具体的です。サーバーはポート1234をリッスンし、IP 127.0.0.1にあります 教師は、「接続」をクリックすると、そのIP上のそのポートに接続しようとするプログラムを教えてくれました。他の人のために働いているので、私のコーディングエラーでなければなりません。

私が接続をクリックすると、プログラムはストリーム上で "GET"という単語を送信します。そこにはすでに接続されているIPアドレスのリストと、次にaのみを含む改行が含まれています。私は抜い

は、プログラムは言葉「REM」を送信し、私は単に私がクラスTCPServerのを持っている

(一般的なリストがある)私のリストからあれば削除する必要があります(私たちは私たち自身をしなければなりませんでした) 、メインコードとしてこれを持っている:私の推測では、あなたの問題があることであるということである

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

お互いにontopステートメントを使用してスタックできます。あなたはナッツのような括弧を入れ子にする必要はありません。 – Will

+0

私は知っている、私は視覚的により魅力的であることがわかります。 – KdgDev

答えて

0

申し訳ありません、これを理解していない可能性があります。このコードを書きましたか?

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(); 
} 

これはどのコンピュータからでも****を吹き飛ばす予定です。無限にループしていて、各ループに新しいスレッドを作成しています。したがって、ループごとに1つの新しいスレッドを作成し、各ループが1ミリ秒かかる場合(非常に遅いと言うことができます)、5秒で5,000スレッドが得られます。それぞれが同じポートで聴きようとしています。

1つのスレッドを使用してみてください。これがコンソールアプリケーションの場合は、Console.ReadLine()を使用して、誰かがEnterキーを押すまでメインスレッドをブロックします。


新しい情報... AcceptTcpClientブロックを使用しますが、新しいスレッドを作成する代わりに、ThreadPoolでキューに入れる必要があります。

+0

はい、私はこれを書いています。しかし、これを考慮してください。 1)サーバーなので、永遠にループする必要があります。サーバーをシャットダウンしません。 2) "tl.AcceptClient();"というループが続かないため、ビットは接続を待って、プログラムを強制的に待ちます。誰かが接続するまで、新しいスレッドはありません。 – KdgDev

+0

さて、それほど悪くない。それでも、すべての接続ごとに新しいスレッドを作成しています。これは良くない。これらのスレッドをThreadPoolにキューイングします。スレッドプールはスレッドを管理して再利用します。 – Will

+0

あなたが言うThreadPool?私は自分のコースをチェックしたことがありません。私はそれを調べ、プログラミング教師に確認します。 私はどのスレッドが何をしているのかを把握することができたかと思った。私はこれが私にとってそれを望むと思っています。 – KdgDev

6

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は、この(コメントテキストはusings以内に「ここで問題だ」を探してください)のように見えますあなたはsr.ReadLine()を呼び出していますが、入力に改行が含まれていないので、決して来ることのない改行を待ってブロックされます。

コマンド文字列(GET/REM)を作成するには、StreamReader.Readを3回呼び出してみてください。 (注:3回はすべてのコマンドが3文字であるためです)。

Readは整数を返しますが、-1(ファイルの終わりを示す)でないことを確認した後、その整数をcharにキャストできます。

+0

ああ..? 3回?私には疑わしいアイデアのように聞こえる、精巧に注意を払う?プロトコルが新しい行を指示すると仮定すれば、ReadLineは完璧なように見えます。 – falstro

+0

ooooh、一度に1文字読む... – falstro

+0

Readは整数を返します...何が良いのですか... – KdgDev