2016-08-18 3 views
0

私は2台のノートパソコンを同じWi-Fiネットワークに接続し、1台は非常に単純なサーバを接続し、もう1台は非常にシンプルなクライアントを接続しています。あるラップトップでサーバーとクライアントの両方を実行すると、問題なく接続できますが、各ラップトップで1つずつ実行すると、クライアントはサーバーに接続できません。他のコンピュータの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); 
      } 
     } 
    } 
} 

最終クラスの1つは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&を作成するセクションの周りにtry catchがあり、タイムアウトのために例外が常にキャッチされます。 –

答えて

3

サーバーマシンでファイアウォール(Windowsファイアウォールなど)がオフになっているか、ポート番号に対してファイアウォールの例外があることを確認してください。

+0

プライベートネットワークのファイアウォールを無効にしましたが、それでも機能しませんでした。ゲストと公共のネットワークでもそれを行うべきですか? –

+0

あなたは間違ったIPアドレスを使用している可能性があります –

+0

IPアドレスとポート番号は正しくありません。なぜなら、同じコンピュータで(そして私のIPアドレスとしてローカルホストを使用していません)両方を実行すると動作するからです。 –

0

Davidさんの回答が正しいです。私はこれまで、プライベートネットワーク用にファイアウォールを無効にしてみました。しかし、私はゲストと公共のネットワークのためのファイアウォールを無効にし、それは治療を働いた。

codenoirが提案したテスト方法も、私のクライアントを除外するのに非常に効果的でした。私はファイアウォールとは何かだった疑いがある、しかし、あなたは、両方

関連する問題