/// <summary>
/// TCP服务端类
/// </summary>
public class SocketService : IDisposable
{
/// <summary>
/// 套接字服务处理类。
/// </summary>
public class EventHandler
{
private SocketService s;
private TaskFactory tf = new TaskFactory(TaskCreationOptions.None, TaskContinuationOptions.None); /// <summary>
/// 构造函数。
/// </summary>
/// <param name="socketService"></param>
public EventHandler(SocketService socketService)
{
this.s = socketService;
} /// <summary>
/// Connections the specified c.
/// </summary>
/// <param name="c">The c.</param>
public void Connection(SocketClient c)
{
if (s.OnConnection != null)
{
s.OnConnection(s, new ClientConnectionEventArgs(s, c));
}
if (s.ServiceHandler != null)
{
tf.StartNew(() =>
{
try
{
s.ServiceHandler.SocketOpened(c);
}
catch (AggregateException ae)
{
ae.Handle((e) => { Logger.Instance.Error("套接字处理消息程序异常。", e); return true; });
}
});
}
} /// <summary>
/// 客户断开。
/// </summary>
/// <param name="c"></param>
public void Disconnect(SocketClient c)
{
if (s.OnDisconnect != null)
{
s.OnDisconnect(s, new ClientDisconnectEventArgs(s, c));
}
if (s.ServiceHandler != null)
{
tf.StartNew(() =>
{
try
{
s.ServiceHandler.SocketClosed(c);
}
catch (AggregateException ae)
{
ae.Handle((e) => { Logger.Instance.Error("套接字处理消息程序异常。", e); return true; });
}
});
}
} /// <summary>
/// 客户接收。
/// </summary>
/// <param name="c"></param>
public void Receive(SocketClient c)
{
if (s.Encoding != null)
{
byte[] tmp = c.Message;
s.Encoding.Decode(c, ref tmp);
c.Message = tmp;
}
if (s.OnReceive != null)
{
s.OnReceive(s, new ClientReceiveEventArgs(s, c));
}
if (s.ServiceHandler != null)
{
tf.StartNew(() =>
{
try
{
s.ServiceHandler.SocketReceived(c, c.Message);
}
catch (AggregateException ae)
{
ae.Handle((e) => { Logger.Instance.Error("套接字处理消息程序异常。", e); return true; });
}
});
}
} /// <summary>
/// 发送数据。
/// </summary>
/// <param name="c"><see cref="客户端"/></param>
public void Send(SocketClient c, ref byte[] data, object stats)
{
if (s.Encoding != null)
s.Encoding.Encode(c, ref data);
if (s.ServiceHandler != null)
{
tf.StartNew(() =>
{
try
{
s.ServiceHandler.SocketSent(c, stats);
}
catch (AggregateException ae)
{
ae.Handle((e) => { Logger.Instance.Error("套接字处理消息程序异常。", e); return true; });
}
});
}
} /// <summary>
/// 闲置时。
/// </summary>
/// <param name="c"></param>
public void Idle(SocketClient c)
{
if (s.ServiceHandler != null)
{
tf.StartNew(() =>
{
try
{
s.ServiceHandler.SocketIdle(c);
}
catch (AggregateException ae)
{
ae.Handle((e) => { Logger.Instance.Error("套接字处理消息程序异常。", e); return true; });
}
});
}
} } /// <summary>
/// 客户端连接事件。
/// </summary>
public event EventHandler<ClientConnectionEventArgs> OnConnection; /// <summary>
/// 客户端接收事件。
/// </summary>
public event EventHandler<ClientReceiveEventArgs> OnReceive; /// <summary>
/// 客户端断开事件。
/// </summary>
public event EventHandler<ClientDisconnectEventArgs> OnDisconnect; private int port;
private System.Net.Sockets.Socket service;
private EventHandler handler;
private Logger log = Logger.Instance;
private bool isdispose = false;
/// <summary>
/// 用指定的端口初始化。
/// </summary>
/// <param name="port"><see cref="端口。"/></param>
public SocketService(int port)
: this(port, null)
{ } /// <summary>
/// Initializes a new instance of the <see cref="SocketService"/> class.
/// </summary>
/// <param name="port">The port.</param>
/// <param name="handler">The handler.</param>
public SocketService(int port, SocketServiceHandler handler)
: this(port, null, handler)
{ } /// <summary>
/// Initializes a new instance of the <see cref="SocketService"/> class.
/// </summary>
/// <param name="port">The port.</param>
/// <param name="encoding">The encoding.</param>
/// <param name="handler">The handler.</param>
public SocketService(int port, SocketEncoding encoding, SocketServiceHandler handler)
{
this.port = port;
this.handler = new EventHandler(this);
this.Encoding = encoding;
this.ServiceHandler = handler;
service = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
} /// <summary>
/// 套接字解码/编码器。
/// </summary>
public SocketEncoding Encoding { get; set; } /// <summary>
/// 服务处理。
/// </summary>
public SocketServiceHandler ServiceHandler { get; set; } /// <summary>
/// 获得处理引擎。
/// </summary>
public EventHandler HandlerEngine { get { return handler; } } /// <summary>
/// 绑定端口。
/// </summary>
public void Bind()
{
service.ExclusiveAddressUse = true;
service.Bind(new IPEndPoint(IPAddress.Any, port));
} /// <summary>
/// Listens this instance.
/// </summary>
public void Listen()
{
service.Listen(1000);
service.BeginAccept(new AsyncCallback(EndAccept), null);
} /// <summary>
/// 监听请求。
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:丢失范围之前释放对象")]
private void EndAccept(IAsyncResult result)
{
try
{
var socket = service.EndAccept(result);
SocketClient.CreateInstance(this, socket);
}
catch (ObjectDisposedException)
{
return;
}
catch (SocketException se)
{
if (se.ErrorCode != 10052 && se.ErrorCode != 10054)
{
log.Error("服务端请求错误:", se);
}
}
catch (System.Exception ex)
{
log.Error("服务端请求错误:", ex);
}
service.BeginAccept(new AsyncCallback(EndAccept), null);
} #region IDisposable 成员 /// <summary>
/// 执行与释放或重置非托管资源相关的应用程序定义的任务。
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} /// <summary>
/// Releases unmanaged and - optionally - managed resources
/// </summary>
/// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool dispose)
{
if (isdispose)
{
return;
}
if (dispose)
{
service.Close();
service.Dispose();
}
isdispose = true;
} ~SocketService()
{
Dispose(false);
} #endregion
}求优化。。求改进。。各种求。。
/// TCP客户端类
/// </summary>
public class SocketClient : IDisposable
{ private System.Net.Sockets.Socket c;
private SocketService server;
private byte[] buf = new byte[4096];
private int buflen = 0;
private bool iscon = true;
private TimerManager timer = null;
private System.Net.IPEndPoint point;
private Map<string, dynamic> dir = new Map<string, dynamic>();
private Logger log = Logger.Instance; /// <summary>
/// 添加属性到客户端。从此以后可以通过索引器索引。
/// </summary>
/// <param name="key"></param>
/// <param name="obj"></param>
public void AddAttribute(string key, dynamic obj)
{
dir.Add(key, obj);
} /// <summary>
/// 删除属性。
/// </summary>
/// <param name="key"></param>
public void RemoveAttribute(string key)
{
dir.Remove(key);
} /// <summary>
/// 访问属性。
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public dynamic this[string key]
{
get
{
return dir[key];
}
set { dir[key] = value; }
} /// <summary>
/// 构造函数,构造新客户端。
/// </summary>
/// <param name="client"><see cref="客户端套接字。"/></param>
private SocketClient(SocketService server, System.Net.Sockets.Socket client)
{
this.c = client;
this.server = server;
this.point = (System.Net.IPEndPoint)c.RemoteEndPoint;
server.HandlerEngine.Connection(this);
c.BeginReceive(buf, 0, buf.Length, SocketFlags.None, new AsyncCallback(EndReceive), null);
} /// <summary>
/// 创建实例。
/// </summary>
/// <param name="server"><see cref="服务端。"/></param>
/// <param name="client"><see cref="客户端。"/></param>
/// <returns></returns>
public static SocketClient CreateInstance(SocketService server, System.Net.Sockets.Socket client)
{
return new SocketClient(server, client);
} /// <summary>
/// 收到的数据。
/// </summary>
public byte[] Message { get; set; } /// <summary>
/// 远程地址。
/// </summary>
public System.Net.IPEndPoint RemoteIP
{
get
{
return point;
}
} private void EndReceive(IAsyncResult result)
{
try
{
buflen = c.EndReceive(result);
if (buflen == 0)
{
this.Dispose();
return;
}
using (System.IO.MemoryStream stream = new System.IO.MemoryStream(buf))//处理数据。
{
byte[] tmp = new byte[buflen];
stream.Read(tmp, 0, tmp.Length);
Message = tmp;
}
server.HandlerEngine.Receive(this);
timer.Reset();
c.BeginReceive(buf, 0, buf.Length, SocketFlags.None, new AsyncCallback(EndReceive), null);
}
catch (SocketException se)
{
if (se.ErrorCode > 10054 && se.ErrorCode < 10052)
{
log.Error("客户端请求接收错误:", se);
}
else
{
this.Dispose();
return;
}
}
catch (ObjectDisposedException)
{
return;//客户端已释放。
}
catch (Exception ex)
{
log.Error("客户端请求接收错误:", ex);
}
} /// <summary>
/// Sets the idel.
/// </summary>
public void SetIdle(long milliseconds)
{
if (timer != null)
{
timer.Dispose();
}
timer = TimerManager.Registry(new Action(Idle), milliseconds);
} /// <summary>
/// Idles this instance.
/// </summary>
private void Idle()
{
server.HandlerEngine.Idle(this);
} /// <summary>
/// Writes the specified data.
/// </summary>
/// <param name="data">The data.</param>
/// <returns><see cref="已发送到 System.Net.Sockets.Socket 的字节数。"/></returns>
[MethodImpl(MethodImplOptions.Synchronized)]//大概是静态方法只能一个线程执行。实例方法也只能一个线程执行。
public int Write(byte[] data, object stats)
{
if (iscon)
{
timer.Reset();
server.HandlerEngine.Send(this, ref data, stats);
return c.Send(data);
}
throw new ObjectDisposedException(this.GetType().ToString());
} /// <summary>
/// Writes the specified data.
/// </summary>
/// <param name="data">The data.</param>
/// <returns></returns>
public int Write(byte[] data)
{
return Write(data, null);
} /// <summary>
/// Writes the specified packet.
/// </summary>
/// <param name="packet">The packet.</param>
/// <returns></returns>
public int Write(MaplePacket packet)
{
return Write(packet.GetBytes(), packet);
} #region IDisposable 成员 /// <summary>
/// 执行与释放或重置非托管资源相关的应用程序定义的任务。
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} /// <summary>
/// Releases unmanaged and - optionally - managed resources
/// </summary>
/// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool dispose)
{
if (!iscon)
{
return;
}
if (dispose)
{
c.Disconnect(false);
c.Close();
if (timer != null)
{
timer.Dispose();
}
Action<SocketClient> del = new Action<SocketClient>(server.HandlerEngine.Disconnect);
del.BeginInvoke(this, null, null);
}
iscon = false;
} ~SocketClient()
{
Dispose(false);
} #endregion
}