【问题标题】:Reconnect to the server重新连接到服务器
【发布时间】:2014-01-01 16:28:28
【问题描述】:

我的 Tcpclient 没有正确断开连接我正在使用客户端异步。
我想在服务器断开连接时自动重新连接。
什么是正确的路径?

这是连接代码

private void Connect_btn_Click(object sender, EventArgs e)
{
    try
    {
        if (IsConnected == false)
        {
            constatus.Text = "Connecting.....";
            newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //IPEndPoint iep = new IPEndPoint(IPAddress.Any, 20);
            IPEndPoint iep = new IPEndPoint(IPAddress.Parse(IP), Convert.ToInt16(PORT));
            newsock.BeginConnect(iep, new AsyncCallback(Connected), newsock); 
        }
        else 
        {
            MessageBox.Show("Connection is Already Connected");
        }
    }
    catch (Exception)
    {
        MessageBox.Show("Please Enter IPAddress and Port Address","Error",MessageBoxButtons.OK,MessageBoxIcon.Information);   
    }
} 

       //This is Connected Function IASYNCHRESLT interface using call back
        //Connected Function Call Back Asynch use in Connection button
  void Connected(IAsyncResult iar)
   {All Commands Inputs Send Fucntion Calling}
    {
        try
        { 
            client = (Socket)iar.AsyncState;
            client.EndConnect(iar);
            this.Invoke(new viewStatus(setValue), "Connected");
            //constatus.Text = "Connected To:" + client.RemoteEndPoint.ToString();
            client.BeginReceive(data, 0, size, SocketFlags.None, new AsyncCallback(ReceiveData), client);
            GetAllDateHide_performClick();
            
        }
        catch (SocketException)
        {
            ErrorConnecting();
        }
    }

这是断开代码

private void ButtonDisconnect_Click(object sender, EventArgs e)
{
    try
    {
        client.Close();
        constatus.Text = "Disconnected";
    }
    catch (Exception) { }
}

以及如何处理我将断开连接的 ObjectDisposed 异常

【问题讨论】:

    标签: c# networking tcp tcpclient


    【解决方案1】:

    首先,我不确定您为什么直接使用套接字而不是使用 TcpClient (documentation)。有原因吗?因为 TcpClient 更干净。

    其次,如果您已经在计划异步,为什么不使用async-await

    最后,我不建议直接从 GUI 进行网络操作。

    关于自动重新连接,我看到了 2 个选项。

    1. 如果操作导致错误,则重新连接。
    2. 让落后的工作人员不时尝试重新连接。

    你还没有展示任何操作,所以我介绍一下我对第二个的看法:

    public class TcpManager
    {
        private TcpClient _tcpClient;
    
        public TcpManager()
        {
            _tcpClient = new TcpClient(AddressFamily.InterNetwork);
            Task.Run(() => ConnectAsync());
        }
    
        private async Task ConnectAsync()
        {
            while (true)
            {
                if (!_tcpClient.Connected)
                {
                    Console.WriteLine("Connecting...");
    
                    try
                    {
                        _tcpClient = new TcpClient(AddressFamily.InterNetwork);
                        await _tcpClient.ConnectAsync(IPAddress.Parse(IP), Convert.ToInt16(PORT));
                        await Task.Delay(TimeSpan.FromSeconds(5));
                    }
                    catch (SocketException e)
                    {
                        Console.WriteLine(e);
                    }
                }
                else
                {
                    Console.WriteLine("Already Connected");
                }
            }
        }
    
        private void Close()
        {
            try
            {
                _tcpClient.Close();
                _tcpClient = new TcpClient(AddressFamily.InterNetwork);
                Console.WriteLine("Disconnected");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
    }
    

    【讨论】:

    • 1.你可以使用pastebin。 2. 对于 codereview.Stackexchange.com,这更像是一个问题。 3.您应该尝试解释这里出了什么问题,以便其他人可以做出贡献。
    • codereview.stackexchange.com/questions/38502/… 这是我的代码,请查看 I3arnon
    • 很多,但我的答案是:使用 TcpClient,async-await,将网络代码移出 UI 到它自己的类,并有一个重建连接的后台任务
    • 这是 .net 4.5 解决方案。4.0 没有 ConnectAsync
    • @DavutGürbüz 您可以使用 BeginConnect 和 EndConnect 构建一个。
    【解决方案2】:

    正如上面的答案,您应该使用 TCP 客户端。不要在应用层单独使用套接字。

    但是即使使用 TCP 客户端并且您拥有很多属性,问题仍然存在。这是因为 TCP/IP 协议强制端口处于 TIME_WAIT 状态。这是出于某些原因,这是另一个话题。 OK,现在你使用的端口必须在这期间等待 140 秒,你不能使用这个端口(这意味着 .net 中的 ipend)。有两种方法可以处理这个烦人的 TIME_WAIT 状态。

    1. 尝试使用 UDP 协议而不是 TCP/IP,因为它是面向连接的。
    2. 如果您坚持使用 TCP/IP 协议,请更改端口号,建立另一个连接。

    【讨论】:

      猜你喜欢
      • 2021-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-23
      • 2016-11-05
      • 2011-09-14
      • 2015-10-09
      • 1970-01-01
      相关资源
      最近更新 更多