方法一
Socket client;
Task.Run(async () =>
{
try
{
int index = 0;
while (true)
{
index++;
await Task.Delay(1000);
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var result = client.BeginConnect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6666), null, null);
bool state = result.AsyncWaitHandle.WaitOne(1000);// 为什么 卡 20秒
// state : 异步动作在1秒时间内完成
if (client.Connected)
{
client.EndConnect(result);// EndConnect不代表断开连接 ,结束这个异步对象
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")}-{DateTime.Now.Millisecond.ToString("000")} [{index.ToString("000")}] 连接成功");
}
else
{
// 连接销毁
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")}-{DateTime.Now.Millisecond.ToString("000")} [{index.ToString("000")}] 连接失败");
}
client.Dispose();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
});
方法二
// 拿到最新的状态
Socket socket = new Socket(
AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
// 三次握手
socket.Connect(new IPEndPoint(IPAddress.Parse("192.168.2.1"), 102));
// 物理线路的断开
// 上位机应用 -------------> PLC
// 上位机应用 --------路由器/交换机 -----(断连)----> PLC
// 第二种情况解决方案:心跳 请求 I0.0(不同的PLC不同处理)->响应false
// Send -> Receive(超时处理) 超时N次时 判断失联
// 单独线程 10秒钟执行一次
Console.WriteLine(socket.Connected);// 保留最后一次操作时的状态,不是实时的状态
while (true)
{
// 心跳请求
Thread.Sleep(1000);
bool state = !(!socket.Connected || (socket.Poll(1, SelectMode.SelectRead) && socket.Poll(1, SelectMode.SelectWrite) && (socket.Available == 0)));// 返回True :连接正常
if (state)
{
Console.WriteLine("连接正常");
socket.Shutdown(SocketShutdown.Both);
socket.Dispose();
}
else
{
Console.WriteLine("连接断开");
socket = new Socket(
AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
try
{
// 大概20秒时间
socket.Connect(new IPEndPoint(IPAddress.Parse("192.168.2.1"), 102));
}
catch (Exception ex)
{
Console.WriteLine("重新连接失败");
Console.WriteLine(ex.Message);
}
var result = socket.BeginConnect(new IPEndPoint(IPAddress.Parse("192.168.2.1"), 102), new AsyncCallback(r =>
{
//
Console.WriteLine(r.AsyncState);
if (!r.IsCompleted) // 连接请求的动作 执行完成 不包括连接状态
socket.EndConnect(r);
Console.WriteLine("回调执行");
}), null);
bool s = result.AsyncWaitHandle.WaitOne(1000);
if (s)// 连接成功后
{
Console.WriteLine("重新连接");
}
else
{
// 连接的时候 异步,在1秒钟时间内 没有连接成功 跳出
try
{
socket.EndConnect(result); // 销毁之前的连接请求 卡线程
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("重连失败");
}
}
//重连 使用 发送业务请求 执行连接判断