重新连接到服务器

时间:2014-01-01 16:28:28

标签: c# networking tcp tcpclient

我的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异常我将断开连接

2 个答案:

答案 0 :(得分:1)

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

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

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

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

  1. 如果操作导致错误,则重新连接。
  2. 让一个落后的工人偶尔尝试重新连接。
  3. 你没有展示任何操作,所以我在第二部分展示了我的看法:

    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 :(得分:0)

如上所述,您应该使用TCP客户端。不要在应用层中使用socket ditectly。

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

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