231 lines
7.3 KiB
C#
231 lines
7.3 KiB
C#
|
|
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}]";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|