2012-04-18 5 views
0

Мне отчаянно нужна помощь. Я по существу создал программу, которая (будет использовать) шифрование для отправки сообщений туда и обратно. Часть шифрования работает нормально, однако я довольно новичок в Threads, и я не могу на всю жизнь получить часть клиентского/серверного приложения. Программа чата - это прямое IP-соединение с использованием TCP, поэтому каждый хост является клиентом и сервером. Проблема, которую я, кажется, испытываю при отладке, заключается в том, что поток сервера либо не готов, когда клиент пытается подключиться к нему, либо если он готов, он не откажется от Thread, чтобы клиент мог подключиться! Я работаю над этим часами, и это очень неприятно. Надеюсь, кто-то может помочь! Я включил свой код ниже. Это мой фрагмент кода из моего MainForm, который строит клиент и сервер аспекты:C# TCP Chat Application Threading

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

}

Это мой ServerSide код:

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

}

клиентской код :

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 Connecion для отправки сервера (в настоящее время я тестирую это на localhost). Спасибо.

ответ

7

В конструкторе класса ServerSide вы забыли инициализировать член tcpPort. Поскольку вы забыли, сервер попытается прослушать порт 0, и клиент попытается подключиться к порту 7865, и он потерпит неудачу.

Попробуйте добавить этот код к конструктору в классе ServerSide.

this.tcpPort = tcpPort; 

Что касается нитей, то могут возникнуть проблемы, если клиентский поток пытается подключиться, прежде чем нить сервер начал слушать. Вы можете использовать цикл, чтобы попытаться подключиться несколько раз (допустим, 10), с тайм-аутом (скажем, 1 секунду), если вам это не удастся. Таким образом, вы будете повторять 10 раз и сдаваться после этого.

+0

+1 Орел глаз! –

+0

Я думаю, что я, возможно, случайно удалил это довольно недавно, цикл for был решением, которое я искал! Эта часть, похоже, работает, спасибо! – Ramrod