【问题标题】:Unable to connect to other instances of the same program via TCP无法通过 TCP 连接到同一程序的其他实例
【发布时间】:2012-02-01 09:02:20
【问题描述】:

我知道这可能已经被问过一千次了,但我似乎找不到任何关于我的案例的具体信息。

我有一个 C# 客户端程序,它必须通过 LAN 连接到客户端的其他实例。要将一个客户端连接到另一个客户端,我使用了 TcpListener/TcpClient 方法。两个实例都有一个监听器,并且能够创建一个新的客户端来相互连接/监听(它与哪个实例启动连接无关)。

为了创建监听器,我使用以下代码:

// In the constructor:
listener = new TcpListener(IPAddress.Any, 32842);
listenThread = new Thread((ThreadStart)ListenForConnections);
listenThread.Name = "ListenThread";
listenThread.IsBackground = true;
listenThread.Start();

// Listening for connections:
private void ListenForConnections()
{
    listener.Start();
    Console.WriteLine("Started listening for connections");
    for (; ; )
    {
        if (listener.Pending())
        {
            using (TcpClient client = listener.AcceptTcpClient())
            {
                // My own layer over the TcpClient.
                AsyncTCPClient other = new AsyncTCPClient(client);
                Console.WriteLine("Connection from " + client.Client.RemoteEndPoint);
                other.Received += DataReceived;
                other.Exception += ExceptionOccurred;
                connections.Add("Player", other);
                other.Start();
            }
        }
        else
        {
            Thread.Sleep(5);
        }
    }
}

要创建并连接到另一个客户端,我使用以下代码:

public void Connect(IPEndPoint other)
{
    if (socket == null)
    {
        socket = new TcpClient(AddressFamily.InterNetwork);
        socket.Client.ReceiveBufferSize = 2 * 1024 * 1024;
    }
    // Should force-close the socket after 5 seconds if it can't be closed automatically.
    socket.LingerState = new LingerOption(true, 5);
    socket.BeginConnect(other.Address, other.Port, ConnectionCallback, other);
    IsConnecting = true;
}

作为参数提供给 BeginConnect 的 ConnectionCallback 如下所示:

private void ConnectionCallback(IAsyncResult result)
{
    IsConnecting = false;
    IsConnected = socket.Connected;
    if (IsConnected)
    {
        IPEndPoint connectedTo = (IPEndPoint)result.AsyncState;
        stream = socket.GetStream();
        if (Connected != null)
        {
            Connected(this, null);
        }
    }
    else
    {
        if (Exception != null)
        {
            RaiseException(new Exception("Unable to connect to host"));
        }
    }
}

但是,每次我到达回调时,TcpClient 都无法连接到另一个实例,并引发 Exception 事件。现在我在互联网(谷歌)搜索时发现它可能与连接两侧的防火墙有关。但是我已经在所有防火墙关闭的情况下对其进行了测试,所以这不可能。

【问题讨论】:

  • 好吧,RaiseException 的异常。但是,它归结为“连接尝试失败,因为连接方在一段时间后没有正确响应,或者建立连接失败,因为连接的主机未能响应 ip:port”
  • 使用 telnet 测试连接,打开命令提示符,然后 telnet ipOfRemoteHost 32842 [enter],这将验证监听器是否正常并且没有网络问题(如果您没有,您可能需要添加 Telnet Windows 功能以前没有这样做过)
  • 您可以 ping 目标 IP 以检查主机是否已启动。您的下一步可能是下载 PuTTY 并尝试远程登录到目标 IP 和端口。否则,您可以使用端口映射器,这是一个轮询 IP 地址范围并报告哪些端口正在侦听/打开的应用程序。否则,请尝试连接到您自己网络上的端点。选择 SMTP、POP3 或 Web 服务器。如果您在 Google 上获取有关与特定服务通信的一些基本信息,它应该会回复您,如果您知道您的代码工作正常。
  • @Tomek,我可以使用 telnet 成功连接到另一个客户端。所以应该没有网络问题吧?

标签: c# tcp


【解决方案1】:

我没有看到回调中调用了 Socket.EndConnect()。 在 MSDN 中看到这个: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.endconnect.aspx

【讨论】:

  • 调用EndConnect()导致应用产生异常“连接尝试失败,因为连接方一段时间后没有正确响应,或者建立连接失败,因为连接的主机没有响应ip :端口”。
  • 这似乎是我的一个愚蠢的错误。在之前的尝试中,我将本地 TcpClient 绑定到特定端口。我更改了它以使其使用系统提供的端口。但是,我尝试使用该端口号连接到程序的另一个实例。在我更改之后,它成功连接。但是,我认为您对 EndConnect() 的调用确实与它有关,因此我将其标记为答案。 :)
猜你喜欢
  • 2021-03-10
  • 2018-02-05
  • 2019-10-17
  • 2017-10-10
  • 1970-01-01
  • 2017-05-16
  • 2018-10-28
  • 2011-10-30
  • 1970-01-01
相关资源
最近更新 更多