Files
6098/Cowain.Bake.Communication/Sokects/TcpSokectClient.cs

231 lines
7.3 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 Cowain.Bake.Common.Core;
using HslCommunication;
using HslCommunication.Core.Net;
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace Cowain.Bake.Communication.Sokects
{
public class TcpSocketClient : NetworkXBase
{
private Encoding encoding;
private object connectLock = new object();
public string Ip { get; set; } = "127.0.0.1";
public int Port { get; set; } = 10000;
// 声明一个事件,通知变量变化
// 定义委托
public delegate void ValueChangedEventHandler(object sender, EventArgs e);
// 声明事件
public event ValueChangedEventHandler ValueChanged;
private bool _isConnected;
public bool IsConnected
{
get { return _isConnected; }
set
{
_isConnected = value;
OnValueChanged();
}
} //CoreSocket.Connected
private int bufferLength = 2048;
private byte[] buffer = null;
// 触发事件的方法
public virtual void OnValueChanged()
{
ValueChanged?.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// 当前的编码器
/// </summary>
public Encoding Encoding
{
get
{
return encoding;
}
set
{
encoding = value;
}
}
/// <summary>
/// 当接收到字符串时候的触发事件
/// </summary>
public event Action<string> ReceivedString;
/// <summary>
/// 实例化一个默认的对象
/// </summary>
//public TcpSocketClient()
//{
// buffer = new byte[bufferLength];
// encoding = Encoding.UTF8;
//}
/// <summary>
/// 使用指定的ip地址和端口号来实例化这个对象
/// </summary>
/// <param name="ipAddress">Ip地址</param>
/// <param name="port">端口号</param>
public TcpSocketClient(string ipAddress, int port)
{
buffer = new byte[bufferLength];
encoding = Encoding.UTF8;
this.Ip = ipAddress;
this.Port = port;
}
/// <summary>
/// 连接服务器
/// </summary>
/// <returns>返回是否连接成功</returns>
public OperateResult ConnectServer()
{
CoreSocket?.Close();
OperateResult<Socket> operateResult = CreateSocketAndConnect(Ip, Port, 5000);
IsConnected = operateResult.IsSuccess;
if (!operateResult.IsSuccess)
{
return operateResult;
}
try
{
CoreSocket = operateResult.Content;
CoreSocket.BeginReceive(buffer, 0, bufferLength, SocketFlags.None, ReceiveCallBack, CoreSocket);
return OperateResult.CreateSuccessResult();
}
catch (Exception ex)
{
LogHelper.Instance.Error("连接MOM系统失败", true);
return new OperateResult(ex.Message);
}
}
/// <summary>
/// 关闭当前的连接对象
/// </summary>
/// <returns>错误信息</returns>
public OperateResult ConnectClose()
{
try
{
CoreSocket?.Close();
return OperateResult.CreateSuccessResult();
}
catch (Exception ex)
{
return new OperateResult(ex.Message);
}
}
/// <summary>
/// 发送字符串到网络上去
/// </summary>
/// <param name="text">文本信息</param>
/// <returns>发送是否成功</returns>
public OperateResult SendString(string text)
{
if (string.IsNullOrEmpty(text))
{
return OperateResult.CreateSuccessResult();
}
return Send(CoreSocket, encoding.GetBytes(text));
}
public OperateResult Send(byte[] text)
{
return Send(CoreSocket, text);
}
private void ReceiveCallBack(IAsyncResult ar)
{
Socket socket = ar.AsyncState as Socket;
if (socket == null)
{
return;
}
byte[] array = null;
try
{
int num = socket.EndReceive(ar);
socket.BeginReceive(buffer, 0, bufferLength, SocketFlags.None, ReceiveCallBack, socket);
if (num == 0)
{
IsConnected = false;
CoreSocket?.Close();
return;
}
array = new byte[num];
Array.Copy(buffer, 0, array, 0, num);
}
catch (ObjectDisposedException)
{
}
catch (Exception ex2)
{
base.LogNet?.WriteWarn(StringResources.Language.SocketContentReceiveException + ":" + ex2.Message);
ThreadPool.QueueUserWorkItem(ReConnectServer, null);
}
if (array != null)
{
this.ReceivedString?.Invoke(encoding.GetString(array));
}
}
/// <summary>
/// 是否是处于重连的状态
/// </summary>
/// <param name="obj">无用的对象</param>
public void ReConnectServer(object obj)
{
base.LogNet?.WriteWarn(StringResources.Language.ReConnectServerAfterTenSeconds);
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
base.LogNet?.WriteWarn($"Wait for connecting server after {9 - i} seconds");
}
OperateResult<Socket> operateResult = CreateSocketAndConnect(Ip, Port, 5000);
IsConnected = operateResult.IsSuccess;
if (!operateResult.IsSuccess)
{
//用于将工作项添加到线程池的方法。它允许你将一个委托Delegate或方法作为参数添加到线程池中以便由线程池中的线程执行
//ThreadPool.QueueUserWorkItem(ReConnectServer, obj); //加上它只要一次重连就可以了不加他就可以执行多次。add by lsm
return;
}
lock (connectLock)
{
try
{
CoreSocket?.Close();
CoreSocket = operateResult.Content;
CoreSocket.BeginReceive(buffer, 0, bufferLength, SocketFlags.None, ReceiveCallBack, CoreSocket);
base.LogNet?.WriteWarn(StringResources.Language.ReConnectServerSuccess);
}
catch (Exception ex)
{
base.LogNet?.WriteWarn(StringResources.Language.RemoteClosedConnection + ":" + ex.Message);
ThreadPool.QueueUserWorkItem(ReConnectServer, obj);
}
}
}
/// <summary>
/// 返回表示当前对象的字符串
/// </summary>
/// <returns>字符串</returns>
public override string ToString()
{
return $"NetPlainSocket[{Ip}:{Port}]";
}
}
}