下面是我的代码,用于启动客户端到服务器的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秒重试一次?
答案 0 :(得分: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错误代码的参考:https://docs.microsoft.com/en-us/windows/desktop/winsock/windows-sockets-error-codes-2
要建立基于时间的重试机制,我将创建某种“连接监视程序”:每X秒有一个计时器检查客户端字段。如果为空,并且尚未运行connection-startup-attempt,请启动一个。
不过,我个人会尝试切换到TPL。但我认为这是您的问题的替代选择,而不是直接答案。但是我推荐。