20220510_191_upperpc/AutomaticApp/Common/Clinet.cs
2023-07-27 10:57:34 +08:00

345 lines
12 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static AutomaticApp.Common.Sockets;
using AutomaticApp.ViewModels;
namespace AutomaticApp.Common
{
public class Clinet : SocketObject
{
public PushSockets pushSockets;
bool IsClose = false;
/// <summary>
/// 当前管理对象
/// </summary>
Sockets sk;
/// <summary>
/// 客户端
/// </summary>
TcpClient client;
/// <summary>
/// 当前连接服务端地址
/// </summary>
IPAddress Ipaddress;
/// <summary>
/// 当前连接服务端端口号
/// </summary>
int Port;
/// <summary>
/// 服务端IP+端口
/// </summary>
IPEndPoint ip;
/// <summary>
/// 发送与接收使用的流
/// </summary>
NetworkStream nStream;
/// <summary>
/// 初始化Socket
/// </summary>
/// <param name="ipaddress"></param>
/// <param name="port"></param>
public override void InitSocket(IPAddress ipaddress, int port)
{
Ipaddress = ipaddress;
Port = port;
ip = new IPEndPoint(Ipaddress, Port);
client = new TcpClient();
}
/// <summary>
/// 初始化Socket
/// </summary>
/// <param name="ipaddress">ipd地址</param>
/// <param name="port">端口</param>
public override void InitSocket(string ipaddress, int port)
{
Ipaddress = IPAddress.Parse(ipaddress);
Port = port;
ip = new IPEndPoint(Ipaddress, Port);
client = new TcpClient();
}
/// <summary>
/// 重写Start方法,其实就是连接服务端
/// </summary>
public override void Start()
{
Connect();
}
/// <summary>
/// 连接
/// </summary>
public bool Connect()
{
if (client != null && IsOnline() && client.Connected)
return true;
try
{
client.Connect(ip);
tools.Logging("连接客户端成功,IP:" + Ipaddress + "端口号:" + Port);
//将是否接收到心跳包判断位 置于false
IsReturnMsg = System.DateTime.Now;
//检测当前连接状态
CheckConnect();
nStream = new NetworkStream(client.Client, true);
sk = new Sockets(ip, client, nStream);
sk.nStream.BeginRead(sk.RecBuffer, 0, sk.RecBuffer.Length, new AsyncCallback(EndReader), sk);
}
catch (Exception)
{
tools.Logging("连接客户端失败,IP:" + Ipaddress + "端口号:" + Port);
return false;
}
return true;
}
public DateTime IsReturnMsg = System.DateTime.Now;
/// <summary>
/// 检查链接状态
/// </summary>
//private async void CheckConnect()
//{
// await Task.Run(() =>
// {
// //连接成功等待5秒后 发送心跳包
// Thread.Sleep(10000);
// tools.Logging("开始发送心跳包");
// while ((System.DateTime.Now - IsReturnMsg).TotalSeconds < 150)
// {
// //如果没有收到心跳包 就发送一次Get
// if (!IsCheckConnect)
// {
// //发送一次GET
// SendData(new byte[] { (byte)'G', (byte)'E', (byte)'T' });
// tools.Logging("发送一次心跳包GET,上一次收到心跳包的时间差为" + (System.DateTime.Now - IsReturnMsg).TotalSeconds + "秒");
// //等待30秒钟
// Thread.Sleep(30000);
// }
// else //如果处于异常断开情况 则不在发送心跳包
// {
// tools.Logging("目前系统由于卫通/下位机原因链接断开停止发送心跳包GET");
// break;
// }
// }
// tools.Logging("停止发送心跳包GET");
// //如果此时还是没有 且不是检查连接状态
// if (!IsCheckConnect)
// {
// //先断开链接
// Stop();
// tools.Logging("心跳包超时主动断开链接停止发送心跳包GET");
// //等待30秒钟
// Thread.Sleep(10000);
// //初始化
// InitSocket(Ipaddress.ToString(), Port);
// //重新链接
// while (!Connect())
// {
// tools.Logging("心跳包超时,重新链接失败!");
// Thread.Sleep(30000);
// }
// tools.Logging("心跳包超时,重新链接成功!");
// }
// });
//}
bool IsCheckConnect = false;
private async void CheckConnect()
{
if (IsCheckConnect)
return;
await Task.Run(() =>
{
IsCheckConnect = true;
//连接成功等待10秒后 发送心跳包
Thread.Sleep(10000);
tools.Logging("开始发送心跳包");
while ((System.DateTime.Now - IsReturnMsg).TotalSeconds < 150)
{
//发送一次Get
SendData(new byte[] { (byte)'G', (byte)'E', (byte)'T' });
tools.Logging("发送一次心跳包GET,上一次收到心跳包的时间差为" + (System.DateTime.Now - IsReturnMsg).TotalSeconds + "秒");
//等待30秒钟
Thread.Sleep(30000);
}
tools.Logging("心跳包超时主动断开链接停止发送心跳包GET");
//先断开链接
Stop();
//等待10秒钟
Thread.Sleep(10000);
//初始化
InitSocket(Ipaddress.ToString(), Port);
tools.Logging("心跳包超时,开始初始化并重新链接!");
IsCheckConnect = false; //允许重新链接并启用异步心跳包
Connect();
Thread.Sleep(10000);
//重新链接
while (!IsOnline())
{
tools.Logging("心跳包超时,重新链接失败!");
Connect();
Thread.Sleep(30000);
}
tools.Logging("心跳包超时,重新链接成功!");
});
}
/// <summary>
/// 读取
/// </summary>
private void EndReader(IAsyncResult ir)
{
Sockets s = ir.AsyncState as Sockets;
try
{
if (s != null)
{
if (IsClose && client == null)
{
sk.nStream.Close();
sk.nStream.Dispose();
return;
}
s.Offset = s.nStream.EndRead(ir);
if (pushSockets != null)
pushSockets.Invoke(s);//推送至UI
if (IsOnline())
{
//Thread.Sleep(100);
sk.nStream.BeginRead(sk.RecBuffer, 0, sk.RecBuffer.Length, new AsyncCallback(EndReader), sk);
}
else
{
if (Ipaddress.ToString().Equals(tools.GetAppSetting("PLC_IP1")))
{
MainWindow.mainViewModel.DoSocket1Connect("断开");
tools.Logging("站点1目前系统由于卫通/下位机原因链接断开IP:" + Ipaddress + "端口号:" + Port);
DoConnect(1);
}
else if (Ipaddress.ToString().Equals(tools.GetAppSetting("PLC_IP2")))
{
MainWindow.mainViewModel.DoSocket2Connect("断开");
tools.Logging("站点2目前系统由于卫通/下位机原因链接断开IP:" + Ipaddress + "端口号:" + Port);
DoConnect(2);
}
}
}
}
catch (Exception skex)
{
Sockets sks = s;
sks.ex = skex;
sks.ClientDispose = true;
if (pushSockets != null)
pushSockets.Invoke(sks);//推送至UI
}
}
private bool IsDoConnect = false;
/// <summary>
/// 检查链接状态
/// </summary>
private async void DoConnect(int id)
{
await Task.Run(() =>
{
tools.Logging("站点" + id + "目前系统由于卫通/下位机原因链接断开IP:" + Ipaddress + "端口号:" + Port + "开始重新连接");
IsDoConnect = true;
while (!IsOnline())
{
Thread.Sleep(15000);
if (id == 1)
MainWindow.mainViewModel.DoSocket1Connect("连接");
if (id == 2)
MainWindow.mainViewModel.DoSocket2Connect("连接");
Thread.Sleep(15000);
}
//如果连接成功则切出检查连接模式
tools.Logging("站点" + id + "目前系统由于卫通/下位机原因链接断开IP:" + Ipaddress + "端口号:" + Port + "重新链接成功,退出重新链接模式");
IsDoConnect = false;
});
}
/// <summary>
/// 停止
/// </summary>
public override void Stop()
{
Sockets sks = new Sockets();
try
{
if (client != null)
{
client.Client.Shutdown(SocketShutdown.Both);
Thread.Sleep(10);
client.Close();
IsClose = true;
client = null;
}
else
{
sks.ex = new Exception("客户端没有初始化.!");
}
if (pushSockets != null)
pushSockets.Invoke(sks);//推送至UI
}
catch (Exception ex)
{
sks.ex = ex;
}
}
/// <summary>
/// 发送消息
/// </summary>
public void SendData(byte[] SendData)
{
try
{
if (client == null || !client.Connected)
{
Sockets sks = new Sockets();
sks.ex = new Exception("客户端无连接..");
sks.ClientDispose = true;
if (pushSockets != null)
pushSockets.Invoke(sks);//推送至UI
}
if (client != null && client.Connected) //如果连接则发送
{
if (nStream == null)
{
nStream = client.GetStream();
}
nStream.Write(SendData, 0, SendData.Length);
}
}
catch (Exception skex)
{
Sockets sks = new Sockets();
sks.ex = skex;
sks.ClientDispose = true;
if (pushSockets != null)
pushSockets.Invoke(sks);//推送至UI
}
}
public bool Is_Connected()
{
return client.Connected;
}
public bool IsOnline()
{
if (client == null)
return false;
return !((client.Client.Poll(1000, SelectMode.SelectRead) && (client.Client.Available == 0)) || !client.Client.Connected);
}
}
}