2012-04-18 12 views
0

私は助けが切望されています。私は本質的にメッセージを前後に送るために暗号化を使うプログラムを作りました。暗号化部分は正常に動作していますが、私はスレッドにはかなり新しいので、私の人生の間、アプリケーションのクライアント/サーバー部分を整列させることができません。チャットプログラムは、TCPを使用した直接IP接続であるため、各ホストはクライアントとサーバーです。クライアントが接続しようとしたときにサーバースレッドが準備が整っていないか、クライアントが接続できるようにスレッドを解放しない場合、デバッグ時に問題が発生しているようです。私はこれを何時間も働いており、とてもイライラしています。誰かが助けてくれることを願っています!私は以下の私のコードを含んだ。C#TCPチャットアプリケーションスレッディング

private void InitializeComponent() { 

     server = new ServerSide("127.0.0.1",7865); 
     servThread = new Thread(new ThreadStart(server.begin)); 
     client = new ClientSide("127.0.0.1",7865); 
     clientThread = new Thread(new ThreadStart(client.begin)); 
     servThread.Start(); 
     clientThread.Start(); 


     //servThread.Join(); 
     //clientThread.Join(); 

}

これは私のサーバーサイドコードです:

public class ServerSide 
{ 
    String IpString; 
    int tcpPort; 
    bool goodToGo = false; 
    System.Net.IPAddress ipAddress = null; 
    public ServerSide(String ip, int tcpPort) 
    { 
     IpString = ip; 
     bool isValidIp = System.Net.IPAddress.TryParse(IpString, out ipAddress); 
     if (isValidIp == true) // check if the IP is valid, set the bool to true if so 
     { 
      goodToGo = true; 
     } 
     else 
     { 
      goodToGo = false; 
     } 
    } 

    public void begin() 
    { 
     try 
     { 
      IPAddress ipAd = IPAddress.Parse(IpString); 

      /* Initializes the Listener */ 
      TcpListener myList = new TcpListener(ipAd, tcpPort); 
      Socket s = null; 
      /* Start Listening at the specified port */ 
      while (true) 
      { 
       myList.Start(); 

       if (myList.Pending()) 
       { 
         s = myList.AcceptSocket(); 
         break; 
       } 

      } 

      String toReceive = ""; 
        while (true) 
        { 
         byte[] b = new byte[4096]; 
         int k = s.Receive(b); 
         for (int i = 0; i < k; i++) 
          toReceive += Convert.ToString((Convert.ToChar(b[i]))); 

         // ASCIIEncoding asen = new ASCIIEncoding(); 

         var form = MainForm.ActiveForm as MainForm; 
         if (form != null) 
         { 
          form.messageReceived(toReceive); 
         } 
         toReceive = ""; 
        } 
       } 
     catch (Exception e) 
     { 
      Console.WriteLine("Error..... " + e.StackTrace); 
     } 
    } 
} 

}

クライアント側コード これは私のコードスニペットは、クライアントとサーバーの側面を構築し、私のMainFormからです:

public class ClientSide 
{ 
    private String IpString; 
    private int tcpPort; 
    private TcpClient tcpInt; 
    private static Stream stm; 
    private System.Net.IPAddress ipAddress = null; 
    private bool goodToGo = false; 

    public ClientSide(String ip, int tcpPort) 
    { 

     IpString = ip; 
     this.tcpPort = tcpPort; 

     bool isValidIp = System.Net.IPAddress.TryParse(IpString, out ipAddress); 
     if (isValidIp == true) 
     { 
      goodToGo = true; 
     } 
     else 
     { 
      goodToGo = false; 
     } 
    } 

    public void begin() 
    { 
     try 
     { 
      tcpInt = new TcpClient(); 
      // Console.WriteLine("Connecting....."); 



      tcpInt.Connect(IpString, tcpPort); 
      // use the ipaddress as in the server program 

      // Console.WriteLine("Connected"); 

      // String str = Console.ReadLine(); 
      stm = tcpInt.GetStream(); 
     } 

     catch (Exception e) 
     { 
      Console.WriteLine("Error..... " + e.StackTrace); 
     } 
    } 


    public void sendMessage(String str) 
    { 
     // stm = tcpInt.GetStream(); 

     ASCIIEncoding asen = new ASCIIEncoding(); 
     byte[] ba = asen.GetBytes(str); 

     stm.Write(ba, 0, ba.Length); 

     /** byte[] bb = new byte[100]; 
     int k = stm.Read(bb, 0, 100); 

     for (int i = 0; i < k; i++) 
      Console.Write(Convert.ToChar(bb[i]));*/ 

    } 
} 

もう一度やり直してください。クライアントは、ホストが積極的に接続を拒否したというエラーを受け取ります。しかし、私はそれらの時刻を知ることができません。私はサーバーがTCP接続をリッスンする方法を探していますが、サーバーを送信するTCP接続を作成するために私の他のスレッドに移動します(現在はlocalhostでこれをテストしています)。おかげさまで

答えて

7

ServerSideクラスのコンストラクタでは、tcpPortメンバの初期化を忘れています。忘れてしまったので、サーバーはポート0をlistenしようとし、クライアントはポート7865に接続しようとしますが、失敗するでしょう。

このコードをServerSideクラスのコンストラクタに追加してみてください。

this.tcpPort = tcpPort; 

サーバスレッドがリスンを開始する前に、クライアントスレッドが接続しようとすると、スレッドが問題になることがあります。ループを使用して何度も接続しようとすると(10と言う)、成功しなかった場合はタイムアウト(1秒と言う)を使用できます。この方法で、あなたは10回再試行し、それをあきらめます。

+0

+1イーグルアイ! –

+0

私は誤ってそれをかなり最近削除したかもしれないと思います、forループは私が探していた解決策でした!その部分は働いているようです、ありがとう! – Ramrod