C#如果连接失败,请始终重试tcp连接

C#如果连接失败,请始终重试tcp连接,c#,.net,sockets,tcp,C#,.net,Sockets,Tcp,以下是启动客户端到服务器的tcp连接的代码: Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client); 连接回调: private void ConnectCallback(IAsyncResult ar)

以下是启动客户端到服务器的tcp连接的代码:

Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
连接回调:

    private void ConnectCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the socket from the state object.  
            Socket client = (Socket)ar.AsyncState;

            // Complete the connection.  
            client.EndConnect(ar);
        }
        catch (Exception ex)
        {
            _logger.Info(ex.ToString());
        }
    }
private void ConnectCallback(IAsyncResult ar)
{
    ConnectionState state = (ConnectionState)ar.AsyncState;
    try
    {
        state.Client.EndConnect(ar);
    }
    catch (SocketException ex)
    {
        _logger.Info(ex.ToString());
        if( state.FailedAttempts < MAX_ATTEMPTS )
        {
            state.FailedAttempts += 1;
            state.Client.BeginConnect( remoteEP, new AsyncCallback(ConnectCallback), state );

            // you may also check the exception for what happened exactly.
            // There may be conditions where retrying does not make sense.
            // See SocketException.ErrorCode
        }
        else
        {
            // You may want to handle exceeding max tries.
            // - Notify User
            // - Maybe throw a custom exception
        }
    }
}
但我的代码只在系统启动时连接一次。如果第一次尝试失败,我们如何重试连接

如果连接总是失败,是否总是要重试

也许每30秒重试一次

client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
如果要跟踪失败的尝试并保持良好的ol'异步模式,我将传递一个状态对象:

class ConnectionState {
    Socket Client {get; set;}
    int FailedAttempts {get; set;} = 0;
}
然后通过:

client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), new ConnectionState(){ .Client = client, FailedAttempts = 0});
在回调中:

private void ConnectCallback(IAsyncResult ar)
{
    ConnectionState state = (ConnectionState)ar.AsyncState;
    try
    {
        state.Client.EndConnect(ar);
    }
    catch (SocketException ex)
    {
        _logger.Info(ex.ToString());
        if( state.FailedAttempts < MAX_ATTEMPTS )
        {
            state.FailedAttempts += 1;
            state.Client.BeginConnect( remoteEP, new AsyncCallback(ConnectCallback), state );

            // you may also check the exception for what happened exactly.
            // There may be conditions where retrying does not make sense.
            // See SocketException.ErrorCode
        }
        else
        {
            // You may want to handle exceeding max tries.
            // - Notify User
            // - Maybe throw a custom exception
        }
    }
}
private void ConnectCallback(IAsyncResult ar)
{
ConnectionState=(ConnectionState)ar.AsyncState;
尝试
{
state.Client.EndConnect(ar);
}
捕获(SocketException例外)
{
_logger.Info(例如ToString());
如果(state.FailedAttempts<最大尝试次数)
{
state.FailedAttempts+=1;
state.Client.BeginConnect(remoteEP,新的异步回调(ConnectCallback),state);
//您还可以检查异常,了解到底发生了什么。
//在某些情况下,重试是没有意义的。
//请参阅SocketException.ErrorCode
}
其他的
{
//您可能希望处理超过最大尝试次数的问题。
//-通知用户
//-可能会引发自定义异常
}
}
}
SocketException错误代码参考:

为了建立一个基于时间的重试机制,我会创建一种“连接看门狗”:每X秒有一个定时器检查客户端字段。如果该值为null且连接启动尝试尚未运行,请启动一个



但就我个人而言,我会尝试改用。但我认为这是一种选择,而不是直接回答你的问题。但我建议您这样做。

如果失败,请从ConnectCallback启动另一个异步调用。如果要设置最大值,请传递失败的尝试次数。是否切换到TPL(异步/等待任务)选项?Fildor,我们如何检查连接是否失败?“SocketException尝试访问套接字时出错。”-无论如何,我都无法捕获
异常。您希望捕获
SocketException
,因为这是您可以并且想要处理的。让其他的冒泡到您的全局异常处理程序。我可以问什么是TPL?如果我想让它永远重试怎么办?不需要max attemptsI为答案添加了一个链接。但是如果你不知道它是什么,阅读它可能会花费你相当长的时间。“如果我想让它永远重试怎么办?”然后在没有检查的情况下开始连接,但我总是给用户取消尝试的可能性。所以,也许让它检查一些布尔ShouldRetryConnection(或类似的东西)。如果我想每隔30秒或1分钟重试一次,该怎么办?