You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

264 lines
5.8 KiB

3 years ago
using EC.Utils.Helper;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
/*******************************************************/
/*
: HFCQMES
:
: Socket通讯
: 1.0
: 2015.09.12
:
:
TODO: */
/*******************************************************/
namespace EC.Utils.SocketHelper
{
public class SocketServer
{
public event EventHandler<string> RecData; //定义一个委托类型的事件
public event EventHandler<byte[]> OnRecData; //定义一个委托类型的事件
public event EventHandler<Tuple<string, string>> OnClientConnected; // 客户端接入事件<IP, Port>
private Boolean canlistening = false;
public int Port = 10000;
private Dictionary<string, Socket> socketLst = new Dictionary<string, Socket>();
public SocketServer(int port)
{
this.Port = port;
}
private ManualResetEvent allDone = new ManualResetEvent(false);
public void StartListening()
{
canlistening = true;
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, Port);
Socket listener = null;
listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(localEndPoint);
listener.Listen(110);
LogUnit.Debug("服务监听端口" + Port);
while (canlistening)
{
allDone.Reset();
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
allDone.WaitOne(); //阻塞主线程
}
}
catch (Exception ex)
{
throw new Exception("listener.Bind=" + ex.ToString());
}
finally
{
listener.Close();
LogUnit.Debug("finally 停止接收");
}
}
public void AcceptCallback(IAsyncResult ar)
{
if (canlistening)
{
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
IPEndPoint endPoint = ((IPEndPoint)handler.RemoteEndPoint);
String clientip = endPoint.Address.ToString();
String clientport = endPoint.Port.ToString();
//设置主线程继续
allDone.Set();
StateObject state = new StateObject();
state.workSocket = handler;
string key = clientip + ":" + clientport;
socketLst.Add(key, handler);
//OnRecData(handler,"客户端:" +key +" 链接");
OnClientConnected?.Invoke(handler, new Tuple<string, string>(clientip, clientport));
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
public void ReadCallback(IAsyncResult ar)
{
try
{
if (!canlistening) return;
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
IPEndPoint clientip = (IPEndPoint)handler.RemoteEndPoint;
String ip = clientip.Address.ToString();
int read = handler.EndReceive(ar);
if (canlistening & read > 0)
{
//处理接收到的命令
// StocketDataWinderPLCHandler micHandler = new StocketDataWinderPLCHandler(state.buffer, 0, read, doffer);
string readDataString = Encoding.UTF8.GetString(state.buffer, 0, read);
#if DEBUG
LogUnit.Debug("rec client ip:" + ip + " readDataString=" + readDataString);
#endif
byte[] newfuf = ByteHelper.SubArr(state.buffer, 0, read);
try
{
OnRecData?.Invoke(handler, newfuf);
RecData.Invoke(handler, readDataString);
}
catch (Exception ex)
{
LogUnit.Error(this.GetType(), ex);
// OnLog?.Invoke(this, ex.Message);
}
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
else
{
if (state.sb.Length > 1)
{
string content = state.sb.ToString();
FileUnit.Log(string.Format("Read {0} bytes from socket.\n Data:{1}", content.Length, content));
}
handler.Close();
handler = null;
}
}
catch (Exception ex)
{
LogUnit.Error(this.GetType(), ex);
}
}
private void RefeshSocketList()
{
FileUnit.Log("MIC RefeshSocketLst len=" + socketLst.Count);
foreach (KeyValuePair<string, Socket> pair in socketLst)
{
Socket socket = pair.Value;
if (socket != null)
{
if (socket.Connected == false)
{
socket = null;
socketLst.Remove(pair.Key);
}
}
else
{
socketLst.Remove(pair.Key);
}
}
}
public void Start()
{
Thread LisThread = new Thread(new ThreadStart(StartListening));
LisThread.Start();
}
public void Stop()
{
canlistening = false;
allDone.Set();
foreach (KeyValuePair<string, Socket> pair in socketLst)
{
Socket socket = pair.Value;
if (socket != null)
{
socket.Close();
}
}
socketLst.Clear();
}
public void ShowClient()
{
FileUnit.Log("Count:" + socketLst.Count);
foreach (KeyValuePair<string, Socket> pair in socketLst)
{
Socket socket = pair.Value;
if (socket != null)
{
FileUnit.Log(pair.Key + " " + socket.Connected.ToString());
}
else
{
socketLst.Remove(pair.Key);
}
}
}
//public Socket GetSocketByIp(string ipAddress)
//{
// if (socketLst.ContainsKey(ipAddress))
// {
// return socketLst[ipAddress];
// }
// else
// {
// return null;
// }
//}
public Socket GetSocketByIp(string clientip)
{
List<string> keys = new List<string>(socketLst.Keys);
for (int i = 0; i < keys.Count; i++)
{
Socket socket = socketLst[keys[i]];
if (socket != null)
{
if (socket.Connected == false)
{
socket = null;
socketLst.Remove(keys[i]);
keys.Remove(keys[i]);
i--;
}
else
{
if (keys[i].StartsWith(clientip))
{
return socket;
}
}
}
else
{
socketLst.Remove(keys[i]);
keys.Remove(keys[i]);
i--;
}
}
return null;
}
}
}