using Aitex.Core.RT.Log;
using Aitex.Core.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MECF.Framework.Common.Net
{
public class JetTcpClient
{
#region 内部变量
private string _ip="127.0.0.1";
private int _port = 9600;
private bool _connected = false;
protected int _reconnectInterval = 500;
protected DateTime _connectTime = DateTime.Now;
private int _connectTimeout = 2000;
private int _receiveTimeout = 1000;
private int _sendTimeout = 1000;
private object _connectLocker=new object();
private object _reconnectLocker = new object();
private object _sendLocker = new object();
private object _receiveLocker = new object();
private object _closeLocker = new object();
private AutoResetEvent _connectAutoResetEvent=new AutoResetEvent(false);
private Socket _socket = null;
#endregion
#region 属性
///
/// 重连间隔时长
///
public int ReconnectInterval { set { _reconnectInterval = value; } }
///
/// 连接超时时长
///
public int ConnectTimeout { set { _connectTimeout = value; } }
///
/// 接收超时时长
///
public int ReceiveTimeout { set { _receiveTimeout = value; } }
///
/// 发送超时时长
///
public int SendTimeout { set { _sendTimeout = value; } }
///
/// 连接状态
///
public bool Connected { get { return _connected; } }
#endregion
///
/// 构造函数
///
///
///
public JetTcpClient(string ip,int port)
{
_ip= ip;
_port= port;
}
///
/// 连接
///
public NetResult Connect()
{
if (_connected)
{
return NetResult.CreateSuccessResult();
}
if(!Monitor.TryEnter(_connectLocker,_connectTimeout))
{
return NetResult.CreateFailedResult(NetErrorCode.LockerOccupied);
}
_connectTime = DateTime.Now;
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.ReceiveTimeout = _receiveTimeout;
_socket.SendTimeout=_sendTimeout;
NetStateObject stateObject=new NetStateObject();
stateObject.Socket = _socket;
stateObject.AutoResetEvent = _connectAutoResetEvent;
EndPoint localEndpoint = _socket.LocalEndPoint;
if(IPAddress.TryParse(_ip,out IPAddress ipAddress))
{
try
{
_socket.BeginConnect(new IPEndPoint(ipAddress, _port), new AsyncCallback(ConnectCallBack), stateObject);
}
catch(Exception ex)
{
stateObject.Dispose();
stateObject = null;
ConnectFailedBusiness();
Monitor.Exit(_connectLocker);
return NetResult.CreateFailedResult((int)NetErrorCode.InnerException, ex.Message);
}
if (!_connectAutoResetEvent.WaitOne(_connectTimeout))
{
stateObject.Dispose();
stateObject = null;
ConnectFailedBusiness();
Monitor.Exit(_connectLocker);
return NetResult.CreateFailedResult(NetErrorCode.ConnectTimeout);
}
LOG.WriteLog(eEvent.EV_DEVICE_INFO, "System", $"Connect {_ip}:{_port} Success,local {localEndpoint}");
_connected = true;
stateObject.Dispose();
stateObject = null;
Monitor.Exit(_connectLocker);
return NetResult.CreateSuccessResult();
}
else
{
stateObject.Dispose();
stateObject = null;
ConnectFailedBusiness();
Monitor.Exit(_connectLocker);
return NetResult.CreateFailedResult(NetErrorCode.InvalidIpAddress);
}
}
///
/// 中止
///
public void Stop()
{
CloseSocket();
}
///
/// 连接失败后处理
///
///
private void ConnectFailedBusiness()
{
_connectAutoResetEvent.Reset();
CloseSocket();
}
///
/// 关闭Socket
///
private void CloseSocket()
{
if (Monitor.TryEnter(_closeLocker, 10))
{
if (_socket != null)
{
try
{
_socket.Shutdown(SocketShutdown.Both);
}
catch
{
}
try
{
_socket.Close();
}
catch
{
}
_socket = null;
_connected = false;
}
Monitor.Exit(_closeLocker);
}
}
///
/// 当连接的结果返回
///
/// 异步对象
private void ConnectCallBack(IAsyncResult ar)
{
if (ar.AsyncState is NetStateObject state)
{
if (state.Socket != null)
{
try
{
state.Socket.EndConnect(ar);
state.AutoResetEvent.Set();
}
catch (Exception ex)
{
}
}
}
}
///
/// 发送数据
///
///
///
public NetResult Send(byte[] data)
{
if(!Connected)
{
return NetResult.CreateFailedResult(NetErrorCode.NetOffline);
}
//清除缓存数据
ClearPreData();
//进入发送
if (Monitor.TryEnter(_sendLocker,_sendTimeout))
{
if(_socket==null)
{
return NetResult.CreateFailedResult(NetErrorCode.NullSocketObject);
}
try
{
_socket.Send(data);
Monitor.Exit(_sendLocker);
return NetResult.CreateSuccessResult();
}
catch (Exception ex)
{
Monitor.Exit(_sendLocker);
ConnectFailedBusiness();
return NetResult.CreateFailedResult((int)NetErrorCode.InnerException, ex.Message);
}
}
else
{
return NetResult.CreateFailedResult(NetErrorCode.GetLockTimeout);
}
}
///
/// 接收数据
///
///
///
public NetResult Receive(int length)
{
if (!Connected)
{
return NetResult.CreateFailedResult(NetErrorCode.NetOffline);
}
if (Monitor.TryEnter(_receiveLocker,_receiveTimeout))
{
if(_socket==null)
{
return NetResult.CreateFailedResult(NetErrorCode.NullSocketObject);
}
try
{
byte[] buffer = null;
if (length == -1)
{
buffer = new byte[_socket.Available];
}
else
{
buffer = new byte[length];
}
_socket.Receive(buffer, length, SocketFlags.None);
Monitor.Exit(_receiveLocker);
return NetResult.CreateSuccessResult(buffer);
}
catch(SocketException ex)
{
Monitor.Exit(_receiveLocker);
ConnectFailedBusiness();
return NetResult.CreateFailedResult((int)NetErrorCode.InnerException, ex.Message);
}
catch (Exception ex)
{
Monitor.Exit(_receiveLocker);
ConnectFailedBusiness();
return NetResult.CreateFailedResult((int)NetErrorCode.InnerException, ex.Message);
}
}
else
{
return NetResult.CreateFailedResult(NetErrorCode.GetLockTimeout);
}
}
///
/// 清除先前的数据
///
public void ClearPreData()
{
if (!Connected)
{
return;
}
if (Monitor.TryEnter(_receiveLocker, _receiveTimeout))
{
if (_socket == null)
{
return;
}
try
{
while (_socket.Available != 0)
{
byte[] buffer = new byte[_socket.Available];
_socket.Receive(buffer, buffer.Length, SocketFlags.None);
}
Monitor.Exit(_receiveLocker);
}
catch (SocketException ex)
{
Monitor.Exit(_receiveLocker);
ConnectFailedBusiness();
}
catch (Exception ex)
{
Monitor.Exit(_receiveLocker);
ConnectFailedBusiness();
}
}
}
}
}