2016-08-18 4 views
0

Итак, у меня есть два ноутбука, подключенных к одной сети Wi-Fi, причем один работает с очень простым сервером, а другой - очень простой клиент, подключающийся к нему. Когда я запускаю как сервер, так и клиент на одном ноутбуке, они подключаются без проблем, но при запуске одного на каждом ноутбуке клиент не может подключиться к серверу.Невозможно подключиться к TCPClient на другом компьютере

Код для сервера заключается в следующем:

using System; 
using System.Net; 
using System.Net.Sockets; 

namespace Utils 
{ 
    /// <summary> 
    /// A base server which handles listening for client connections and has simple API to communicate back and forth 
    /// </summary> 
    public class BaseServer 
    { 
     #region Properties and Fields 

     /// <summary> 
     /// The listener we can use to detect incoming connections from clients to the server 
     /// </summary> 
     private TcpListener Listener { get; set; } 

     /// <summary> 
     /// Our interface to the single client we are supporting for now 
     /// </summary> 
     public Comms ClientComms { get; private set; } 

     /// <summary> 
     /// Determines whether we have clients connected 
     /// </summary> 
     public bool Connections { get; private set; } 

     #endregion 

     public BaseServer() 
     { 
      Listener = new TcpListener(IPAddress.Any, 1490); 
      Listener.Start(); 

      ListenForNewClient(); 
     } 

     /// <summary> 
     /// Starts an asynchronous check for new connections 
     /// </summary> 
     private void ListenForNewClient() 
     { 
      Listener.BeginAcceptTcpClient(AcceptClient, null); 
     } 

     /// <summary> 
     /// Callback for when a new client connects to the server 
     /// </summary> 
     /// <param name="asyncResult"></param> 
     protected virtual void AcceptClient(IAsyncResult asyncResult) 
     { 
      ClientComms = new Comms(Listener.EndAcceptTcpClient(asyncResult)); 
      ClientComms.OnDataReceived += ProcessMessage; 

      ListenForNewClient(); 
     } 

     #region Message Callbacks 

     /// <summary> 
     /// A function which is called when the Client sends a message to the server. 
     /// Override to perform custom message handling 
     /// </summary> 
     /// <param name="data"></param> 
     protected virtual void ProcessMessage(byte[] data) { } 

     #endregion 

    } 
} 

И код для клиента заключается в следующем:

using System; 
using System.Net.Sockets; 

namespace Utils 
{ 
    /// <summary> 
    /// A base client class which connects and communicates with a remote server 
    /// </summary> 
    public class BaseClient 
    { 
     #region Properties and Fields 

     /// <summary> 
     /// The interface to the server 
     /// </summary> 
     public Comms ServerComms { get; private set; } 

     #endregion 

     public BaseClient(string ipAddress, int portNumber = 1490) 
     { 
      // Attempt to connect 
      try 
      { 
       ServerComms = new Comms(new TcpClient(ipAddress, portNumber)); 
       ServerComms.OnDataReceived += OnMessageReceived; 
       ServerComms.OnDisconnect += OnServerDisconnect; 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Connection failed"); 
      } 
     } 

     #region Callbacks 

     /// <summary> 
     /// A function which is called when this client receives a message. 
     /// Override to perform behaviour when custom messages arrive. 
     /// </summary> 
     /// <param name="data"></param> 
     protected virtual void OnMessageReceived(byte[] data) { } 

     /// <summary> 
     /// A function called when this client can no longer communicate to the server it is connected to 
     /// </summary> 
     protected virtual void OnServerDisconnect() { } 

     #endregion 
    } 
} 

Сервер запускается из основного цикла, как это:

using System; 

namespace BuildServer 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      BaseServer server = new BaseServer(); 
      while (true) 
      { 

      } 
     } 
    } 
} 

и Клиент запускается следующим образом:

using System; 
using Utils; 

namespace BuildServerClient 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      BaseClient client = new BaseClient(); 

      while (true) 
      { 
       Console.WriteLine("Ready"); 
       string message = Console.ReadLine(); 
       client.ServerComms.Send(message); 
      } 
     } 
    } 
} 

Один последний класс - это класс Comms, который действительно является оберткой вокруг TCPClient и не используется в настоящее время, но я добавляю его для того же самого полноты.

using System; 
using System.IO; 
using System.Net.Sockets; 
using System.Text; 
using static Utils.Delegates; 

namespace Utils 
{ 
    /// <summary> 
    /// An interface to a client. 
    /// Hides the nuts and bolts and provides a public interface of just data input and output from a data sender/receiver. 
    /// </summary> 
    public class Comms 
    { 
     #region Properties and Fields 

     private TcpClient Client { get; set; } 
     private MemoryStream ReadStream { get; set; } 
     private MemoryStream WriteStream { get; set; } 
     private BinaryReader Reader { get; set; } 
     private BinaryWriter Writer { get; set; } 

     /// <summary> 
     /// Useful buffer for reading packeted messages from the server 
     /// </summary> 
     private byte[] ReadBuffer { get; set; } 

     /// <summary> 
     /// An event that is fired when this Comms receives a message 
     /// </summary> 
     public event OnDataReceived OnDataReceived; 

     /// <summary> 
     /// An event that is fired when this Comms can no longer communicate with the client sending it messages 
     /// </summary> 
     public event OnDisconnect OnDisconnect; 

     #endregion 

     public Comms(TcpClient client) 
     { 
      Client = client; 
      ReadStream = new MemoryStream(); 
      WriteStream = new MemoryStream(); 
      Reader = new BinaryReader(ReadStream); 
      Writer = new BinaryWriter(WriteStream); 

      ReadBuffer = new byte[2048]; 
      Client.NoDelay = true; 

      StartListening(); 
     } 

     #region Data Sending Functions 

     /// <summary> 
     /// Convert a string to a byte array and then send to our client 
     /// </summary> 
     /// <param name="client"></param> 
     /// <param name="str"></param> 
     public void Send(string str) 
     { 
      SendByteArray(Encoding.UTF8.GetBytes(str)); 
     } 

     /// <summary> 
     /// Send a byte array to our client 
     /// </summary> 
     /// <param name="client"></param> 
     /// <param name="bytes"></param> 
     protected void SendByteArray(byte[] bytes) 
     { 
      Writer.Write(bytes); 

      int bytesWritten = (int)WriteStream.Position; 
      byte[] result = new byte[bytesWritten]; 

      WriteStream.Position = 0; 
      WriteStream.Read(result, 0, bytesWritten); 
      WriteStream.Position = 0; 

      Client.GetStream().BeginWrite(result, 0, result.Length, null, null); 
      Writer.Flush(); 
     } 

     #endregion 

     #region Data Receiving Functions 

     /// <summary> 
     /// Start listening for messages from the server 
     /// </summary> 
     private void StartListening() 
     { 
      try 
      { 
       Client.GetStream().BeginRead(ReadBuffer, 0, 2048, StreamReceived, null); 
      } 
      catch 
      { 
       OnDisconnect?.Invoke(); 
      } 
     } 

     /// <summary> 
     /// Callback which processes a message sent from the server 
     /// </summary> 
     /// <param name="ar"></param> 
     private void StreamReceived(IAsyncResult ar) 
     { 
      int bytesRead = 0; 
      try 
      { 
       lock (Client.GetStream()) 
       { 
        bytesRead = Client.GetStream().EndRead(ar); 
       } 
      } 
      catch { } 

      //Create the byte array with the number of bytes read 
      byte[] data = new byte[bytesRead]; 

      //Populate the array 
      for (int i = 0; i < bytesRead; i++) 
      { 
       data[i] = ReadBuffer[i]; 
      } 

      OnDataReceived?.Invoke(data); 

      //Listen for new data 
      StartListening(); 
     } 

     #endregion 
    } 
} 

IP-адреса и номера портов являются правильными и, так как он работает, когда работает на той же машине, я думал, что это может быть проблемой брандмауэра или что-то? Есть ли у кого-нибудь идеи относительно того, что может вызвать эту проблему?

+0

Что идет не так точно? –

+0

Не подключается и время. В разделе, где я создаю TCPClient &, вы пытаетесь поймать попытку, и он всегда выдает исключение из-за таймаута. –

ответ

3

Убедитесь, что брандмауэр (брандмауэр Windows или что-то еще там) отключен на серверной машине или существует исключение брандмауэра для вашего номера порта.

+0

Я отключил брандмауэр для частных сетей, но он все еще не работал. Должен ли я также делать это для гостевых и общедоступных сетей? –

+0

Возможно, вы используете неправильный IP-адрес –

+0

Нет IP-адреса и номера порта, так как все работает, когда я запускаю оба на одном компьютере (и я не использую локальный хост как мой IP-адрес). –

0

Ответ Дэвида был верным. Я ранее пробовал его с отключением брандмауэра для частных сетей. Тем не менее, я отключил брандмауэр для гостевых и общедоступных сетей, и это сработало.

Метод тестирования, предложенный codenoir, также очень эффективен для исключения моего клиента. Я подозревал, что это было что-то делать с брандмауэром, но как только Вы исключаете невозможное ...

Благодаря как