197 lines
4.5 KiB
C#
197 lines
4.5 KiB
C#
|
using System;
|
|||
|
using System.Linq;
|
|||
|
using System.Net;
|
|||
|
using System.Net.Sockets;
|
|||
|
using System.Text;
|
|||
|
using Aitex.Core.RT.Log;
|
|||
|
|
|||
|
namespace MECF.Framework.Common.Communications
|
|||
|
{
|
|||
|
public class AsynSocketServer : IDisposable
|
|||
|
{
|
|||
|
public delegate void ErrorHandler(string args);
|
|||
|
|
|||
|
public delegate void MessageHandler(string message);
|
|||
|
|
|||
|
public delegate void BinaryMessageHandler(byte[] message);
|
|||
|
|
|||
|
private static object _locker = new object();
|
|||
|
|
|||
|
private string _ip;
|
|||
|
|
|||
|
private int _port;
|
|||
|
|
|||
|
private bool _isAscii;
|
|||
|
|
|||
|
private static int _bufferSize = 1021;
|
|||
|
|
|||
|
private Socket _clientSocket;
|
|||
|
|
|||
|
private Socket _serverSocket;
|
|||
|
|
|||
|
private byte[] _buffer;
|
|||
|
|
|||
|
public string NewLine { get; set; }
|
|||
|
|
|||
|
public bool NeedLog { get; set; } = true;
|
|||
|
|
|||
|
|
|||
|
public bool IsConnected => _serverSocket != null;
|
|||
|
|
|||
|
public event ErrorHandler OnErrorHappened;
|
|||
|
|
|||
|
public event MessageHandler OnDataChanged;
|
|||
|
|
|||
|
public event BinaryMessageHandler OnBinaryDataChanged;
|
|||
|
|
|||
|
public AsynSocketServer(string ip, int port, bool isAscii, string newline = "\r")
|
|||
|
{
|
|||
|
_ip = ip;
|
|||
|
_port = port;
|
|||
|
_isAscii = isAscii;
|
|||
|
_serverSocket = null;
|
|||
|
NewLine = newline;
|
|||
|
}
|
|||
|
|
|||
|
~AsynSocketServer()
|
|||
|
{
|
|||
|
Dispose();
|
|||
|
}
|
|||
|
|
|||
|
public void Start()
|
|||
|
{
|
|||
|
if (_serverSocket == null)
|
|||
|
{
|
|||
|
IPEndPoint localEP = new IPEndPoint(IPAddress.Parse(_ip), _port);
|
|||
|
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
|||
|
_serverSocket.Bind(localEP);
|
|||
|
_serverSocket.Listen(10);
|
|||
|
AsyncAccept(_serverSocket);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void AsyncAccept(Socket serverSocket)
|
|||
|
{
|
|||
|
serverSocket.BeginAccept(delegate(IAsyncResult asyncResult)
|
|||
|
{
|
|||
|
_clientSocket = serverSocket.EndAccept(asyncResult);
|
|||
|
LOG.Info($"Received client {_clientSocket.RemoteEndPoint} connect request", isTraceOn: false);
|
|||
|
AsyncReveive();
|
|||
|
}, null);
|
|||
|
}
|
|||
|
|
|||
|
private void AsyncReveive()
|
|||
|
{
|
|||
|
_buffer = new byte[_bufferSize];
|
|||
|
try
|
|||
|
{
|
|||
|
_clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceiveCallback, null);
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
LOG.Write(ex);
|
|||
|
string text = $"TCP Socket recevice data failed:{ex.Message}";
|
|||
|
LOG.Error($"Communication {_ip}:{_port:D} {text}.");
|
|||
|
this.OnErrorHappened(text);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void ReceiveCallback(IAsyncResult asyncResult)
|
|||
|
{
|
|||
|
int num = _clientSocket.EndReceive(asyncResult);
|
|||
|
if (num > 0)
|
|||
|
{
|
|||
|
if (_isAscii)
|
|||
|
{
|
|||
|
string @string = Encoding.ASCII.GetString(_buffer, 0, num);
|
|||
|
LOG.Info($"Client message:{@string}", isTraceOn: false);
|
|||
|
this.OnDataChanged(@string);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
byte[] array = new byte[num];
|
|||
|
for (int i = 0; i < num; i++)
|
|||
|
{
|
|||
|
array[i] = _buffer[i];
|
|||
|
}
|
|||
|
LOG.Info("Client message: " + string.Join(" ", array) + ".", isTraceOn: false);
|
|||
|
this.OnBinaryDataChanged(array);
|
|||
|
}
|
|||
|
}
|
|||
|
_buffer = new byte[_bufferSize];
|
|||
|
_clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceiveCallback, _clientSocket);
|
|||
|
}
|
|||
|
|
|||
|
public void Write(string sendMessage)
|
|||
|
{
|
|||
|
if (_clientSocket == null || sendMessage == string.Empty)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
byte[] data = new byte[1024];
|
|||
|
data = Encoding.ASCII.GetBytes(sendMessage);
|
|||
|
try
|
|||
|
{
|
|||
|
_clientSocket.BeginSend(data, 0, data.Length, SocketFlags.None, delegate(IAsyncResult asyncResult)
|
|||
|
{
|
|||
|
int num = _clientSocket.EndSend(asyncResult);
|
|||
|
LOG.Info($"Communication {_ip}:{_port:D} Send {data}.", isTraceOn: false);
|
|||
|
}, null);
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
LOG.Write(ex);
|
|||
|
string text = $"TCP连接发生错误:{ex.Message}";
|
|||
|
LOG.Error($"Communication {_ip}:{_port:D} {text}.");
|
|||
|
this.OnErrorHappened(text);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void Write(byte[] data)
|
|||
|
{
|
|||
|
if (_clientSocket == null || data.Count() == 0)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
try
|
|||
|
{
|
|||
|
_clientSocket.BeginSend(data, 0, data.Length, SocketFlags.None, delegate(IAsyncResult asyncResult)
|
|||
|
{
|
|||
|
int num = _clientSocket.EndSend(asyncResult);
|
|||
|
LOG.Info($"Communication {_ip}:{_port:D} Send {data}.", isTraceOn: false);
|
|||
|
}, null);
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
LOG.Write(ex);
|
|||
|
string text = $"TCP连接发生错误:{ex.Message}";
|
|||
|
LOG.Error($"Communication {_ip}:{_port:D} {text}.");
|
|||
|
this.OnErrorHappened(text);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void Dispose()
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
if (_serverSocket != null)
|
|||
|
{
|
|||
|
if (IsConnected)
|
|||
|
{
|
|||
|
_serverSocket.Shutdown(SocketShutdown.Both);
|
|||
|
}
|
|||
|
_serverSocket.Close();
|
|||
|
_serverSocket.Dispose();
|
|||
|
_serverSocket = null;
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
LOG.Write(ex);
|
|||
|
string args = $"释放socket资源失败:{ex.Message}";
|
|||
|
this.OnErrorHappened(args);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|