2015-02-14 2 views
0

В настоящее время я участвую в программировании приложения для чатов, которое использует сервер. Пока все работает нормально, если я запускаю сервер и несколько экземпляров приложения на одной машине. Когда я пытаюсь запустить сервер на одном компьютере и фактическое приложение чата у другого, я получаю исключение, которое гласит: «попытка подключения не удалась, потому что связанная сторона не ответила должным образом через какое-то время или установив соединение не удалось, потому что подключенный хост не смог ответить (Ipaddress) (порт)»TCP chat client/server не работает off localhost

сервера код сторона:

using System; 
using System.Net; 
using System.Net.Sockets; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading.Tasks; 
using System.Collections; 
using System.Text; 
using System.Threading; 

namespace ChatAppServer 
{ 
    class Program 
    { 
     public static Hashtable ClientList = new Hashtable(); 
     const int PORT = 321; 
     string localIp; 


     static void Main(string[] args) 
     { 


      TcpListener sckServer = new TcpListener(PORT); 
      TcpClient sckClient = default(TcpClient); 
      int counter = 0; 

      sckServer.Start(); 
      Console.WriteLine("Chat Server is now Running ...."); 
      counter = 0; 
      //Parser myParser = new Parser(); 
      while (true) 
      { 
       counter = counter + 1; 
       sckClient = sckServer.AcceptTcpClient(); 

       string clientData = ""; 
       byte[] recieveData = new byte[10025]; 

       NetworkStream netStream = sckClient.GetStream(); 
       netStream.Read(recieveData, 0, (int)sckClient.ReceiveBufferSize); 
       clientData = System.Text.Encoding.ASCII.GetString(recieveData); 
       clientData = clientData.Substring(0, clientData.IndexOf("$")); 

       ClientList.Add(clientData, sckClient); 

       Broadcast(clientData + " joined the chat", clientData, false); 

       Console.WriteLine(clientData + " connected to the chat"); 
       handleClient client = new handleClient(); 
       client.ClientStart(sckClient, clientData, ClientList); 
      } 
      sckClient.Close(); 
      sckServer.Stop(); 
      Console.WriteLine("exit"); 
      Console.ReadLine(); 
     } 


     public static void Broadcast(string msg, string userName, bool flag) 
     { 
      foreach (DictionaryEntry Item in ClientList) 
      { 
       TcpClient sckBroadcast; 
       sckBroadcast = (TcpClient)Item.Value; 
       NetworkStream broadcastStream = sckBroadcast.GetStream(); 
       Byte[] broadcastData = null; 

       if (flag == true) 
       { 
        broadcastData = Encoding.ASCII.GetBytes(userName + ": " + msg); 
       } 
       else 
       { 
        broadcastData = Encoding.ASCII.GetBytes(msg); 
       } 
       broadcastStream.Write(broadcastData, 0, broadcastData.Length); 
       broadcastStream.Flush(); 
      } 
     } 

     public class handleClient 
     { 
      TcpClient sckClient; 
      string clId; 
      Hashtable ClientList; 

      public void ClientStart(TcpClient inSckClient, string clientId, Hashtable clist) { 
       this.sckClient = inSckClient; 
       this.clId = clientId; 
       this.ClientList = clist; 
       Thread ctThread = new Thread(runChat); 
       ctThread.Start(); 
      } 
      private void runChat() { 
       int requestCount = 0; 
       byte[] recieveData = new byte[10025]; 
       string clientData = ""; 
       string rCount = null; 

       while ((true)) 
       { 
        try 
        { 
         requestCount += 1; 
         NetworkStream netStream = sckClient.GetStream(); 
         netStream.Read(recieveData, 0, (int)sckClient.ReceiveBufferSize); 
         clientData = System.Text.Encoding.ASCII.GetString(recieveData); 
         clientData = clientData.Substring(0, clientData.IndexOf("$")); 
         Console.WriteLine(clId + " : " + clientData); 
         rCount = Convert.ToString(requestCount); 

         Program.Broadcast(clientData, clId, true); 


        } 
        catch(Exception ex) 
        { 
         Console.WriteLine(ex.ToString()); 
        } 
       } 
      } 

     } 
    } 
} 

чат код приложения номер:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
//Need for the application 
using System.Net; 
using System.Net.Sockets; 
using System.Threading; 


namespace ChatApp 
{ 
    public partial class Form1 : Form 
    { 
     System.Net.Sockets.TcpClient sckClient = new System.Net.Sockets.TcpClient(); 
     NetworkStream svrStream = default(NetworkStream); 
     string recieveData = null; 

     public Form1() 
     { 
      InitializeComponent(); 
      btnSend.Enabled = false; 
     } 
     private void btnConnect_Click(object sender, EventArgs e) 
     { 
      recieveData = "Connected to Server"; 
      msg(); 
      int serverPort = Convert.ToInt32(txtServerPort.Text); 
      sckClient.Connect(txtServerIp.Text, serverPort); 
      svrStream = sckClient.GetStream(); 

      byte[] outStream = System.Text.Encoding.ASCII.GetBytes(txtUserName.Text + "$"); 
      svrStream.Write(outStream, 0, outStream.Length); 
      svrStream.Flush(); 

      Thread ctThread = new Thread(MessageCallBack); 
      btnSend.Enabled = true; 
      btnConnect.Enabled = false; 
      txtUserName.Enabled = false; 
      txtServerIp.Enabled = false; 
      txtServerPort.Enabled = false; 
      ctThread.Start(); 

     } 

     private void MessageCallBack() 
     { 
      while(true) 
      { 
       svrStream = sckClient.GetStream(); 
       int buffSize = 0; 
       byte[] inStream = new byte[10025]; 
       buffSize = sckClient.ReceiveBufferSize; 
       svrStream.Read(inStream, 0, buffSize); 
       string returnData = System.Text.Encoding.ASCII.GetString(inStream); 
       recieveData = "" + returnData; 
       msg(); 
      } 
     } 
     //function to display data strings 
     private void msg() 
     { 
      if (this.InvokeRequired) 
      { 
       this.Invoke(new MethodInvoker(msg)); 
      } 
      else 
      { 
       lstMessage.Items.Add(recieveData); 
      } 
     } 



     private void btnSend_Click(object sender, EventArgs e) 
     { 
      byte[] outStream = System.Text.Encoding.ASCII.GetBytes(txtMessage.Text + "$"); 
      svrStream.Write(outStream, 0, outStream.Length); 
      svrStream.Flush(); 
      txtMessage.Text = ""; 
     } 
+0

Правильный IP-адрес? Брандмауэры отключены? Вы только * слушаете * на "localhost"? – BradleyDotNET

+0

Каким IP-адресом вы подключаетесь и порт? Добро пожаловать в StackOverflow! Это звучит как проблема с одним из ваших брандмауэров компьютеров или неправильным IP (использование компьютера, отличного от вашего компьютера, но в локальной сети обычно требуется IP-адрес 192.168.0.X). – Cyral

+0

- это порт, который уже используется на удаленный сервер – MethodMan

ответ

0

у меня есть две проблемы с вашим кодом:

  • Не используйте значение .ReceiveBufferSize, потому что это другое значение длины вашего байтового массива. И вы можете иметь исключение из диапазона вне диапазона.

  • У вас возникла проблема параллелизма на стороне сервера. Более 1 потока попытайтесь получить доступ к ClientList, и эта коллекция не является потокобезопасной..

Чтобы решить эту проблему, вы можете изменить значение ключевого слова lock

private static object _lock = new object(); 
//... 
lock (_lock) 
{ 
    ClientList.Add(clientData, sckClient); 
} 

lock (_lock) 
{ 
    Broadcast(clientData + " joined the chat", clientData, false); 
} 
//... 
lock (_lock) 
{ 
    Program.Broadcast(clientData, clId, true); 

} 

Как вы новичок, я хотел бы дать вам несколько советов.

  • Попробуйте использовать асинхронные сетевые функции (лучше, чем необработанные потоки), an example there.
  • В C# есть много руководств по безопасности с отдельными соединениями (с чем-то другим, лучше, чем ключевое слово lock).