【问题标题】:TcpClient.ConnectAsync and TcpClient.BeginConnect always returning true in Xamarin.Forms Android ApplicationTcpClient.ConnectAsync 和 TcpClient.BeginConnect 在 Xamarin.Forms Android 应用程序中始终返回 true
【发布时间】:2020-07-12 21:24:55
【问题描述】:

我在我的 Xamarin.Forms 项目中创建了一个应用程序,我可以使用 TCP 连接将我的 Android 手机连接到我的计算机。我发现同时使用 TcpClient.ConnectAsync 和 TcpClient.BeginConnect 时,即使端口未打开,它们都返回 client.Connected 为真。我已经验证了这一点,因为我尝试了随机 IP 和随机端口,但仍然显示连接成功。

当使用 TcpClient.ConnectAsync 时,它不会返回 true,除非我按下运行 Button_Clicked 下的代码的按钮 2 次,但是当使用 TcpClient.BeginConnect 时,client.Connected 总是返回 true。我知道客户端没有连接的事实,因为我有一个检测系统,当连接丢失时,它会将用户踢到重新连接页面。

我在 MainPage.xaml.cs 中的 TCPClient 代码:

TcpClient client = new TcpClient();
private async void Button_Clicked(object sender, EventArgs e)
{
    await client.ConnectAsync(ipAddress.Text, Convert.ToInt32(Port.Text));

    if (client.Connected)
    {
        await DisplayAlert("Connected", "The client has successfully connected", "OK");
    }
    else
    {
        await DisplayAlert("Connection Unsuccessful", "The client couldn't connect!", "OK");
    }
}

我也尝试过使用来自How to set the timeout for a TcpClient? 的 TcpClient.BeginConnect:

TcpClient client = new TcpClient();
private async void Button_Clicked(object sender, EventArgs e)
{
    var result = client.BeginConnect(ipAddress.Text, Convert.ToInt32(Port.Text), null, null);
    var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(1));

    if (success)
    {
        await DisplayAlert("Connected", "The client has successfully connected", "OK");
    }
    else
    {
        await DisplayAlert("Connection Unsuccessful", "The client couldn't connect!", "OK");
    }
}

我尝试查找问题,但我发现的唯一内容是:TcpClient.Connected returns true yet client is not connected, what can I use instead? 但是,此链接说明 client.Connected bool 在断开连接后仍然为真,而我的问题是它说即使客户端连接也是如此客户端永远不会与服务器建立真正的连接。

该项目目前使用 .NET Standard 2.0

【问题讨论】:

  • '这表示客户端在断开连接后仍保持连接。'不,不是。 Connected 属性仅表示您在过去的某个时间确实 连接过。它并不表示连接的当前状态。
  • @user207421 这不是我面临的问题。我只是在其中添加了该部分,以说明我遇到的问题有所不同,因此不会将其作为重复项关闭。我的意思是该属性表明客户端保持连接。我的 TcpClient.Connected 属性发生的情况是,它总是在没有真正连接的情况下返回 true。我不知道为什么会发生这种情况,我想出解决它的唯一方法是完全处置客户端并重新实例化它。
  • 属性不'声明客户端保持连接'。这就是我的观点。它表明您确实在以前的某个时间连接过它。即使对等方断开连接,它仍然是正确的。
  • 无论如何,如果你只是要在连接阶段阻塞,你为什么不使用阻塞模式呢?为什么要使用异步模式,或者非阻塞模式?
  • @user207421 我知道它并没有说明客户端保持连接,除了使用该方法之外,我还实现了一种检查断开连接的方法。我还计划添加一种阻塞功能,但我做了一个测试并将超时设置为 1000 毫秒,发现问题只是在您尝试连接时,而它已经在尝试连接。为什么会这样?

标签: android networking xamarin.forms tcp .net-standard-2.0


【解决方案1】:

我发现它会返回 client.Connected 为 true 的原因是因为在客户端仍在尝试连接且尚未超时时运行相同的 ConnectAsync/BeginConnect 方法两次将导致 client.Connected 值出于某种原因是真的。

解决此问题的唯一方法是等待超时完成,或者如果超时太长,则处理客户端并创建一个新客户端。

【讨论】:

  • 不是“出于某种原因”。因为我说的原因。你连接了它。所以它显示为已连接。这里真正的问题似乎是您正在尝试重新-连接套接字。即使连接失败,您也不能这样做。您必须关闭它并创建一个新的。
  • @user207421 是的,我知道,这不是我要说的......当我输入一些随机 IP 和端口时,它表示连接成功。我是说它在不应该连接时声明客户端已连接。我知道这是一个事实,因为尝试将数据包发送到 IP 和端口会导致异常说客户端甚至没有连接到端口。我使用随机 IP 和端口的原因是向自己展示 client.Connected 值即使在不存在的端口上也会以 true 响应。客户端从未连接到端口,但客户端一直说是。
  • 客户端和服务器之间从未成功连接,在连接尝试超时之前尝试运行连接函数(connectasync 或 beginconnect)会出现此问题。我试图弄清楚为什么它会设置 client.connected 为 true 时甚至没有一个连接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-08
  • 2023-03-20
  • 2011-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多