Socket 服务端
异步模式,收到请求后马上返回
namespace SocketTest
{
public delegate byte[] IResponse(byte[] a,IPEndPoint b);
public delegate void IErrorRedirect(string format,params object[] ea);
public delegate void IInfoRedirect(string format, params object[] ea);
public class SocketServer
{
#region Private
private ManualResetEvent _Lock = new ManualResetEvent(false);
private Socket _Listener;
private int _MaxCount = 100;
private int _Port;
private IPAddress _IP = null;
private bool _Stoping = false;
private int _ThreadCount = 0;
private object _ThreadCountLock = new object();
#endregion
#region Base Method
/// <summary>
/// 初始化Socket服务器
/// </summary>
/// <param name="port">端口</param>
/// <param name="maxCount">最大监听数</param>
public SocketServer(int port, int maxCount)
{
this._Port = port;
this._MaxCount = maxCount;
Regex reg = new Regex("^(\\d+\\.){3}\\d+$");
foreach (IPAddress eachIp in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
{
if (reg.IsMatch(eachIp.ToString()))
{
_IP = eachIp;
break;
}
}
ResponseMethod = null;
ErrorRedirect = null;
InfoRedirect = null;
}
/// <summary>
/// 初始化Socket服务器
/// </summary>
/// <param name="ip">IP地址</param>
/// <param name="port">端口</param>
/// <param name="maxCount">最大监听数</param>
public SocketServer(string ip, int port, int maxCount)
{
this._Port = port;
this._MaxCount = maxCount;
_IP = IPAddress.Parse(ip);
ResponseMethod = null;
ErrorRedirect = null;
InfoRedirect = null;
}
/// <summary>
/// 默认的响应方法
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
private byte[] GetResponseData(byte[] a,IPEndPoint b)
{
return Encoding.UTF8.GetBytes("Response");
}
/// <summary>
/// 开始运行
/// </summary>
public void Run()
{
if (ResponseMethod == null)
ResponseMethod = this.GetResponseData;
if (ErrorRedirect == null)
ErrorRedirect = Console.WriteLine;
if (InfoRedirect == null)
InfoRedirect = Console.WriteLine;
InfoRedirect("");
InfoRedirect("#{0} Start Listening {1}:{2}....", DateTime.Now, _IP, _Port);
InfoRedirect("#Fields: Date Time IP Request-Length Response-Length Time-Taken");
this.ThreadCount = 0;
this._Stoping = false;
Thread t = new Thread(Listen);
t.Start();
}
private void Listen()
{
try
{
ThreadCount += 1;
IPEndPoint localIpEndPoint = new IPEndPoint(_IP, _Port);
_Listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_Listener.Bind(localIpEndPoint);
_Listener.Listen(_MaxCount);
bool runListen = true;
while (runListen && !_Stoping)
{
_Lock.Reset();
_Listener.BeginAccept(new AsyncCallback(AcceptCallBack), null);
_Lock.WaitOne();
}
}
catch (Exception ex)
{
ErrorRedirect("Error 3:{0}", ex.ToString());
}
finally
{
ThreadCount -= 1;
}
}
private void AcceptCallBack(IAsyncResult iar)
{
try
{
ThreadCount += 1;
_Lock.Set();
if (this._Stoping)
return;
Socket currentSocket = _Listener.EndAccept(iar);
RequestData currentSocketObj = new RequestData(currentSocket);
currentSocket.BeginReceive(currentSocketObj.TmpData, 0, currentSocketObj.TmpDataSize, 0, new AsyncCallback(ProcessRequest), currentSocketObj);
}
catch (Exception ex)
{
ErrorRedirect("Error 2:{0}", ex.ToString());
}
finally
{
ThreadCount -= 1;
}
}
#endregion
#region Public
/// <summary>
/// 线程数
/// </summary>
public int ThreadCount{
get
{
return _ThreadCount;
}
private set
{
lock (_ThreadCountLock)
{
_ThreadCount = value;
}
}
}
/// <summary>
/// 处理Socket请求的方法
/// </summary>
public IResponse ResponseMethod { private get; set; }
/// <summary>
/// 错误输出方法
/// </summary>
public IErrorRedirect ErrorRedirect { private get; set; }
/// <summary>
/// 信息输出方法
/// </summary>
public IInfoRedirect InfoRedirect { private get; set; }
/// <summary>
/// 根目录
/// </summary>
public string Root { get; set; }
/// <summary>
/// 停止Socket服务器
/// </summary>
public void Stop()
{
this._Stoping = true;
InfoRedirect("#Stoping");
}
/// <summary>
/// 重启Socket服务器
/// </summary>
public void Restart()
{
InfoRedirect("#{0} Restarting...",DateTime.Now);
Stop();
//发送解锁信号
_Lock.Set();
Stopwatch t = new Stopwatch();
while (true)
{
Thread.Sleep(1000);
if (this.ThreadCount < 1)
break;
if (t.ElapsedMilliseconds > 40000)
{
t.Reset();
return;
}
}
_Listener.Close();
this.Run();
}
#endregion
private void ProcessRequest(IAsyncResult iar)
{
RequestData currentSocketObj = (RequestData)iar.AsyncState;
Socket currentSocket = currentSocketObj.CurrentSocket;
ThreadCount += 1;
try
{
if (this._Stoping)
{
currentSocketObj.Close();
return;
}
currentSocketObj.RemoteEndPoint = (IPEndPoint)currentSocket.RemoteEndPoint;
int byteLen = currentSocket.EndReceive(iar);
Console.WriteLine("Got {0}",byteLen);
if (byteLen > 0)
{
if (currentSocketObj.Data == null)
{//首段数据
currentSocketObj.Watch.Start();
}
currentSocketObj.AppendData(currentSocketObj.TmpData, byteLen);
if (byteLen != currentSocketObj.TmpDataSize)
{
//最后一段
//获取响应数据
byte[] ResponseData = ResponseMethod(currentSocketObj.Data, currentSocketObj.RemoteEndPoint);
//currentSocket.Send(ResponseData, ResponseData.Length, 0);
currentSocket.BeginSend(ResponseData, 0, ResponseData.Length, 0, new AsyncCallback(SendCallback), currentSocketObj);
//Console.WriteLine("{1} Response {0}",currentSocketObj.RemoteEndPoint.ToString(),DateTime.Now.TimeOfDay.ToString());
currentSocketObj.Watch.Stop();
InfoRedirect("{0} {1} {2} {3} {4} #{5}",
DateTime.Now,
currentSocketObj.RemoteEndPoint.ToString(),
currentSocketObj.Length,
ResponseData.Length,
currentSocketObj.Watch.ElapsedMilliseconds,
ThreadCount);
currentSocketObj.Reset();
}
currentSocket.BeginReceive(currentSocketObj.TmpData, 0, currentSocketObj.TmpDataSize, 0, new AsyncCallback(ProcessRequest), currentSocketObj);
}
}
catch (Exception ex)
{
currentSocketObj.Reset();
ErrorRedirect("Error 1:{0}", ex.ToString());
}
finally
{
ThreadCount -= 1;
}
}
private void SendCallback(IAsyncResult iar)
{
RequestData currentSocketObj = (RequestData) iar.AsyncState;
currentSocketObj.CurrentSocket.EndSend(iar);
Console.WriteLine("{0} Send Success {1}\r\n--",DateTime.Now.TimeOfDay.ToString(),currentSocketObj.RemoteEndPoint.ToString());
}
}
/// <summary>
/// Socket请求中的数据
/// </summary>
public class RequestData
{
#region Property
/// <summary>
/// 请求数据
/// </summary>
public byte[] Data { get; set; }
/// <summary>
/// 锁
/// </summary>
private object _Lock = new object();
/// <summary>
/// 临时数据
/// </summary>
public byte[] TmpData;
/// <summary>
/// 临时数据长度
/// </summary>
public readonly int TmpDataSize = 1024;
/// <summary>
/// 请求数据长度
/// </summary>
public int Length { get; set; }
/// <summary>
/// 当前Socket
/// </summary>
public Socket CurrentSocket = null;
/// <summary>
/// 客户端IP端口信息
/// </summary>
public IPEndPoint RemoteEndPoint { get; set; }
/// <summary>
/// 计时器
/// </summary>
public Stopwatch Watch = new Stopwatch();
#endregion
/// <summary>
/// 初始化
/// </summary>
/// <param name="obj"></param>
public RequestData(Socket obj)
{
CurrentSocket = obj;
TmpData = new byte[TmpDataSize];
this.Data = null;
}
/// <summary>
/// 添加请求数据
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
public void AppendData(byte[] data,int length)
{
lock (_Lock)
{
if (Data == null)
{
Data = new byte[length];
Array.Copy(data, 0, Data, 0, length);
this.Length = length;
}
else
{
int newLen = Data.Length + length;
byte[] newData = new byte[newLen];
Data.CopyTo(newData, 0);
// data.CopyTo(newData, Data.Length);
Array.Copy(data, 0, Data, 0, length);
Data = null;
Data = newData;
this.Length = newLen;
}
}
}
/// <summary>
/// 重置当前SocketObj内容
/// </summary>
public void Reset()
{
this.Watch.Reset();
this.Data = null;
}
/// <summary>
/// 关闭套接字
/// </summary>
public void Close()
{
Reset();
if (CurrentSocket.Connected)
{
CurrentSocket.Shutdown(SocketShutdown.Both);
CurrentSocket.Close();
}
else
{
try
{
CurrentSocket.Shutdown(SocketShutdown.Both);
CurrentSocket.Close();
}
catch
{
return;
}
}
}
}
}