初始化版本

This commit is contained in:
LL
2025-11-14 16:12:32 +08:00
commit ea40f18aa6
326 changed files with 137063 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
namespace NetWorkHelper.TCP
{
partial class ITcpClient
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@@ -0,0 +1,624 @@
using NetWorkHelper.ICommond;
using NetWorkHelper.IModels;
using System;
using System.ComponentModel;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace NetWorkHelper.TCP
{
public partial class ITcpClient : Component
{
//#region 读取ini文件
//[DllImport("kernel32")]
//private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
///// <summary>
///// 读出INI文件
///// </summary>
///// <param name="Section">项目名称(如 [TypeName] )</param>
///// <param name="Key">键</param>
//public string IniReadValue(string Section, string Key)
//{
// StringBuilder temp = new StringBuilder(500);
// int i = GetPrivateProfileString(Section, Key, "", temp, 500, System.AppDomain.CurrentDomain.BaseDirectory + "MESConfig.ini");
// return temp.ToString();
//}
static int connecttimeout = 4000;
static int receivetimeout = 2000;
//static int sleeptime;
static int timeoutsend = 3;
//public void ReadINI()
//{
// //string dialog;
// //dialog = System.AppDomain.CurrentDomain.BaseDirectory + "MESConfig.ini";
// //ControlINI mesconfig = new ControlINI(dialog);
// //连接设置
// connecttimeout = Convert.ToInt32(IniReadValue("MESConfig", "connectTimeout")); ;
// receivetimeout = Convert.ToInt32(IniReadValue("MESConfig", "receiveTimeout"));
// _reConnectTime = Convert.ToInt32(IniReadValue("MESConfig", "sleepTime"));
// timeoutsend = Convert.ToInt32(IniReadValue("MESConfig", "timeoutSend"))+1;
//}
//#endregion
#region
public ITcpClient()
{
//ReadINI();
InitializeComponent();
}
public ITcpClient(IContainer container)
{
container.Add(this);
InitializeComponent();
}
#endregion
#region
public IClient Client = null;
private Thread _startThread = null;
private int _reConnectCount = 0;//重连计数
private int _maxConnectCount => timeoutsend;
private ConncetType _conncetType = ConncetType.Conncet;
private bool _isReconnect = true;//是否开启断开重连
private int _reConnectTime;//重连间隔时间
private bool _isStart = false;// 是否启动
private System.Timers.Timer _timer = new System.Timers.Timer(); // 连接后两秒未成功重连
//bool timeoutreconnected=true;//连接超时的重连
//bool datareconnected = true;//接收不到心跳包的重连
#endregion
#region
/// <summary>
/// 服务端IP
/// </summary>
private string _serverip = "127.0.0.1";
[Description("服务端IP")]
[Category("TCP客户端")]
public string ServerIp
{
set { _serverip = value; }
get { return _serverip; }
}
/// <summary>
/// 服务端监听端口
/// </summary>
private int _serverport = 5000;
[Description("服务端监听端口")]
[Category("TCP客户端")]
public int ServerPort
{
set { _serverport = value; }
get { return _serverport; }
}
/// <summary>
/// 网络端点
/// </summary>
private IPEndPoint _ipEndPoint = null;
[Description("网络端点,IP+PORT")]
[Category("TCP客户端")]
internal IPEndPoint IpEndPoint
{
get
{
try
{
IPAddress ipAddress = null;
ipAddress = string.IsNullOrEmpty(ServerIp)
? IPAddress.Any
: IPAddress.Parse(CommonMethod.HostnameToIp(ServerIp));
_ipEndPoint = new IPEndPoint(ipAddress, ServerPort);
}
catch
{
}
return _ipEndPoint;
}
}
/// <summary>
/// 是否重连
/// </summary>
[Description("是否重连")]
[Category("TCP客户端")]
public bool IsReconnection
{
set { _isReconnect = value; }
get { return _isReconnect; }
}
/// <summary>
/// 设置断开重连时间间隔单位毫秒默认3000毫秒
/// </summary>
[Description("设置断开重连时间间隔单位毫秒默认3000毫秒")]
[Category("TCP客户端")]
public int ReConnectionTime
{
get { return _reConnectTime; }
set { _reConnectTime = value; }
}
[Description("设置断开重连时间间隔单位毫秒默认3000毫秒")]
[Category("TCP客户端"), Browsable(false)]
public bool IsStart
{
get { return _isStart; }
set { _isStart = value; }
}
#endregion
#region
private readonly object _threadLock = new object();
public void StartConnect()
{
if (IsStart)
return;
lock (_threadLock)
{
if (_startThread == null || !_startThread.IsAlive)
{
_startThread = new Thread(StartThread);
_startThread.IsBackground = true;
_startThread.Start();
}
}
}
/// <summary>
/// 启动客户端基础的一个线程
/// </summary>
private void StartThread()
{
if (_conncetType == ConncetType.ReConncet && IsReconnection && !IsStart) //如果是重连的延迟N秒
{
Thread.Sleep(ReConnectionTime);
if (IsReconnection)
{
TcpClientStateInfo(string.Format("正在重连..."), SocketState.Reconnection);
}
try
{
_timer.Interval = connecttimeout;
_timer.Elapsed += Timer_Elapsed;
_timer.AutoReset = false;
_timer.Start();
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.ReceiveTimeout = receivetimeout;
socket.SendTimeout = 1000;
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, true);
socket.BeginConnect(IpEndPoint, new AsyncCallback(AcceptCallback), socket);
//timeoutreconnected = true;//连接超时的重连
//datareconnected = true;//接收不到心跳包的重连
}
catch (Exception ex)
{
_timer.Stop();
TcpClientErrorMsg(string.Format("连接服务器失败,错误原因:{0},行号{1}", ex.Message, ex.StackTrace));
if (IsReconnection)
{
Reconnect();
}
}
}
else if (!IsStart)
{
if (IsReconnection)
{
TcpClientStateInfo("正在连接服务器... ...", SocketState.Connecting);
try
{
_timer.Interval = connecttimeout;
_timer.Elapsed += Timer_Elapsed;
_timer.AutoReset = false;
_timer.Start();
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.ReceiveTimeout = receivetimeout;
socket.SendTimeout = 1000;
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, true);
socket.BeginConnect(IpEndPoint, new AsyncCallback(AcceptCallback), socket);
//timeoutreconnected = true;//连接超时的重连
//datareconnected = true;//接收不到心跳包的重连
}
catch (Exception ex)
{
_timer.Stop();
TcpClientErrorMsg(string.Format("连接服务器失败,错误原因:{0},行号{1}", ex.Message, ex.StackTrace));
if (IsReconnection)
{
Reconnect();
}
}
}
}
}
//连接超时则重新连接
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (IsReconnection)
{
//datareconnected = false;//接收不到心跳包的重连
TcpClientErrorMsg(string.Format("连接服务器失败"));
//if (Client != null)
//{
// ShutdownClient(Client);
// Client.WorkSocket.Close();
//}
Reconnect();
//reconnected = false;
}
}
/// <summary>
/// 当连接服务器之后的回调函数
/// </summary>
/// <param name="ar">TcpClient</param>
private void AcceptCallback(IAsyncResult ar)
{
_timer.Stop();
try
{
IsStart = true;
Socket socket = (Socket)ar.AsyncState;
socket.EndConnect(ar);
Client = new IClient(socket);
Client.WorkSocket.BeginReceive(Client.BufferInfo.ReceivedBuffer, 0, Client.BufferInfo.ReceivedBuffer.Length, 0, new AsyncCallback(ReadCallback), Client);
_conncetType = ConncetType.Conncet;
TcpClientStateInfo(string.Format("已连接服务器"), SocketState.Connected);
_reConnectCount = 0;
//timeoutreconnected = false;//连接超时的重连
//datareconnected = false;//接收不到心跳包的重连
}
catch (SocketException ex)
{
IsStart = false;
string msg = ex.Message;
if (ex.NativeErrorCode.Equals(10060))
{
//无法连接目标主机
msg = string.Format("{0} 无法连接: error code {1}!", "", ex.NativeErrorCode);
}
else if (ex.NativeErrorCode.Equals(10061))
{
msg = string.Format("{0} 主动拒绝正在重连: error code {1}!", "", ex.NativeErrorCode);
}
else if (ex.NativeErrorCode.Equals(10053))
{
//读写时主机断开
msg = string.Format("{0} 主动断开连接: error code {1}! ", "", ex.NativeErrorCode);
}
else
{
//其他错误
msg = string.Format("Disconnected: error code {0}!", ex.NativeErrorCode);
}
if (IsReconnection)
{
TcpClientErrorMsg(string.Format("连接服务器失败,错误原因:{0}", msg));
Reconnect();
}
}
catch (Exception ex)
{
}
}
#endregion
#region
/// <summary>
/// 重连模块
/// </summary>
private void Reconnect()
{
if (Client != null)
{
ShutdownClient(Client);
Client?.WorkSocket?.Close();
Client = null;
}
if (_conncetType == ConncetType.Conncet)
{
TcpClientStateInfo(string.Format("已断开服务器{0}", IsReconnection ? ",准备重连" : ""), SocketState.Disconnect);
}
if (!IsReconnection)
{
return;
}
_reConnectCount++;//每重连一次重连的次数加1
if (_conncetType == ConncetType.Conncet)
{
_conncetType = ConncetType.ReConncet;
//CommonMethod.EventInvoket(() => { ReconnectionStart(); });
}
_isStart = false;
if (_startThread != null)
{
try
{
// 检查线程状态,避免重复启动
if (_startThread.IsAlive)
{
// 给线程一个机会正常结束
if (!_startThread.Join(500)) // 等待500毫秒
{
try
{
_startThread.Abort(); // 强制终止
}
catch (ThreadStateException)
{
// 线程可能已经终止,忽略此异常
}
}
}
}
catch (Exception ex)
{
// 记录异常但不阻止重连
Console.WriteLine($"清理线程时异常: {ex.Message}");
}
finally
{
_startThread = null; // 确保设置为null
}
}
if (_reConnectCount < _maxConnectCount && IsReconnection)
{
StartConnect();
}
else
{
_timer.Stop();
StopConnect();
this.IsReconnection = false;
_reConnectCount = 0;
TcpClientStateInfo(string.Format("超过最大重连数,已断开服务器连接"), SocketState.Disconnect);
}
}
#endregion
#region
public void SendData(byte[] data)
{
try
{
if (data == null || data.Length == 0)
{
return;
}
if (Client != null && Client.WorkSocket != null && Client.WorkSocket.Connected)
{
//异步发送数据
//cModel.ClientSocket.Send(data);
Client.WorkSocket.BeginSend(data, 0, data.Length, 0, new AsyncCallback(SendCallback), Client);
//timeoutreconnected = false;//连接超时的重连
//datareconnected = true;//接收不到心跳包的重连
}
}
catch (SocketException ex)
{
TcpClientErrorMsg(string.Format("向服务端发送数据时发生错误,错误原因:{0},行号{1}", ex.Message, ex.StackTrace));
}
}
public bool IsConnected
{
get
{
try
{
return Client != null &&
Client.WorkSocket != null &&
Client.WorkSocket.Connected;
}
catch
{
return false;
}
}
}
/// <summary>
/// 发送完数据之后的回调函数
/// </summary>
/// <param name="ar">Clicent</param>
private void SendCallback(IAsyncResult ar)
{
IClient iClient = (IClient)ar.AsyncState;
if (iClient == null)
return;
Socket handler = iClient.WorkSocket;
try
{
int bytesSent = handler.EndSend(ar);
}
catch (Exception ex)
{
TcpClientErrorMsg(string.Format("发送数据后回调时发生错误,错误原因:{0},行号{1}", ex.Message, ex.StackTrace));
}
}
#endregion
#region
/// <summary>
/// 当接收到数据之后的回调函数
/// </summary>
/// <param name="ar"></param>
private void ReadCallback(IAsyncResult ar)
{
if (Client == null || !_isStart)
return;
Socket handler = Client.WorkSocket;
try
{
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0 && bytesRead <= Client.BufferInfo.ReceivedBuffer.Length)
{
byte[] bytes = new byte[bytesRead];
Array.Copy(Client.BufferInfo.ReceivedBuffer, 0, bytes, 0, bytesRead);
TcpClientRecevice(bytes);
handler.BeginReceive(Client.BufferInfo.ReceivedBuffer, 0, Client.BufferInfo.ReceivedBuffer.Length,
0, new AsyncCallback(ReadCallback), Client);
}
else
{
if (IsReconnection)
{
Reconnect();
}
}
}
catch (Exception ex)
{
//if (datareconnected)
//{
// timeoutreconnected = false;//连接超时的重连
////IsStart = false;
StopConnect();
TcpClientErrorMsg(string.Format("接收数据失败,错误原因:{0},行号{1}", ex.Message, ex.StackTrace));
Reconnect();
//}
}
}
#endregion
#region
/// <summary>
/// 关闭相连的scoket以及关联的StateObject,释放所有的资源
/// </summary>
public void StopConnect()
{
IsStart = false;
if (Client != null)
{
var workSocket = Client.WorkSocket; // 提前保存引用
ShutdownClient(Client);
workSocket?.Close();
//if (Client.WorkSocket != null)
//{
// Client.WorkSocket.Close();
// //Client.WorkSocket?.Dispose();
//}
}
_conncetType = ConncetType.Conncet;
_reConnectCount = 0;//前面三个初始化
}
public void ShutdownClient(IClient iClient)
{
try
{
iClient.WorkSocket.Shutdown(SocketShutdown.Both);
}
catch
{
}
}
#endregion
#region
#region OnRecevice接收数据事件
[Description("接收数据事件")]
[Category("TcpClient事件")]
public event EventHandler<TcpClientReceviceEventArgs> OnRecevice;
protected virtual void TcpClientRecevice(byte[] data)
{
if (OnRecevice != null)
CommonMethod.EventInvoket(() => { OnRecevice(this, new TcpClientReceviceEventArgs(data)); });
}
#endregion
#region OnErrorMsg返回错误消息事件
[Description("返回错误消息事件")]
[Category("TcpClient事件")]
public event EventHandler<TcpClientErrorEventArgs> OnErrorMsg;
protected virtual void TcpClientErrorMsg(string msg)
{
if (OnErrorMsg != null)
CommonMethod.EventInvoket(() => { OnErrorMsg(this, new TcpClientErrorEventArgs(msg)); });
}
#endregion
#region OnStateInfo连接状态改变时返回连接状态事件
[Description("连接状态改变时返回连接状态事件")]
[Category("TcpClient事件")]
public event EventHandler<TcpClientStateEventArgs> OnStateInfo;
protected virtual void TcpClientStateInfo(string msg, SocketState state)
{
if (OnStateInfo != null)
CommonMethod.EventInvoket(() => { OnStateInfo(this, new TcpClientStateEventArgs(msg, state)); });
}
#endregion
#endregion
}
public enum ConncetType
{
Conncet,
ReConncet,
DisConncet
}
}