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

问题描述 投票:2回答:1

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

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

client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);

ConnectCallback:

    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());
        }
    }

但是我的代码只在我的系统启动时才进行一次连接。如果第一次尝试失败,我们如何重试连接?

如果连接总是失败,总会重试吗?

也许每30秒重试一次?

c# .net sockets tcp
1个回答
0
投票
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);

如果你想跟踪失败的尝试并希望保持良好的'异步模式,我会传递一个状态对象:

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
        }
    }
}

SocketException ErrorCodes的引用:https://docs.microsoft.com/en-us/windows/desktop/winsock/windows-sockets-error-codes-2

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


就个人而言,我会尝试切换到TPL。但我认为这是一个替代方案,而不是你问题的直接答案。但我推荐它。

© www.soinside.com 2019 - 2024. All rights reserved.