服务器核心代码 AsyncServer.cs
/// <summary>
/// 异步SOCKET 服务器
/// </summary>
public class AsyncServer : IDisposable
{
#region Fields
/// <summary>
/// 服务器程序允许的最大客户端连接数
/// </summary>
private int _maxClient
/// <summary>
/// 当前的连接的客户端数
/// </summary>
private int _clientCount
/// <summary>
/// 服务器使用的异步socket
/// </summary>
private Socket _serverSock
/// <summary>
/// 客户端会话列表
/// </summary>
private List<session>_clients
private bool disposed = false
#endregion
#region Properties
/// <summary>
/// 服务器是否正在运行
/// </summary>
public bool IsRunning { getprivate set}
/// <summary>
/// 监听的IP地址
/// </summary>
public IPAddress Address { getprivate set}
/// <summary>
/// 监听的端口
/// </summary>
public int Port { getprivate set}
/// <summary>
/// 通信使用的编码
/// </summary>
public Encoding Encoding { getset}
#endregion
#region Ctors
/// <summary>
/// 异步Socket TCP服务器
/// </summary>
///<param name="listenPort">监听的端口
public AsyncServer(int listenPort)
: this(IPAddress.Any, listenPort,1024)
{
}
/// <summary>
/// 异步Socket TCP服务器
/// </summary>
///<param name="localEP">监听的终结点
public AsyncServer(IPEndPoint localEP)
: this(localEP.Address, localEP.Port,1024)
{
}
/// <summary>
/// 异步Socket TCP服务器
/// </summary>
///<param name="localIPAddress">监听的IP地址
///<param name="listenPort">监听的端口
///<param name="maxClient">最大客户端数量
public AsyncServer(IPAddress localIPAddress, int listenPort,int maxClient)
{
this.Address = localIPAddress
this.Port = listenPort
this.Encoding = Encoding.Default
_maxClient = maxClient
_clients = new List<session>()
_serverSock = new Socket(localIPAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
}
#endregion
#region Server
/// <summary>
/// 启动服务器
/// </summary>
/// <returns>异步TCP服务器</returns>
public AsyncServer Start()
{
if (!IsRunning)
{
IsRunning = true
_serverSock.Bind(new IPEndPoint(this.Address, this.Port))
_serverSock.Listen(1024)
_serverSock.BeginAccept(new AsyncCallback(HandleAcceptConnected), _serverSock)
}
return this
}
/// <summary>
/// 启动服务器
/// </summary>
///<param name="backlog">
/// 服务器所允许的挂起连接序列的最大长度
///
/// <returns>异步TCP服务器</returns>
public AsyncServer Start(int backlog)
{
if (!IsRunning)
{
IsRunning = true
_serverSock.Bind(new IPEndPoint(this.Address, this.Port))
_serverSock.Listen(backlog)
_serverSock.BeginAccept(new AsyncCallback(HandleAcceptConnected), _serverSock)
}
return this
}
/// <summary>
/// 停止服务器
/// </summary>
/// <returns>异步TCP服务器</returns>
public AsyncServer Stop()
{
if (IsRunning)
{
IsRunning = false
_serverSock.Close()
//TODO 关闭对所有客户端的连接
}
return this
}
#endregion
#region Receive
/// <summary>
/// 处理客户端连接
/// </summary>
///<param name="ar">
private void HandleAcceptConnected(IAsyncResult ar)
{
if (IsRunning)
{
Socket server = (Socket)ar.AsyncState
Socket client = server.EndAccept(ar)
//检查是否达到最大的允许的客户端数目
if (_clientCount == _maxClient)
{
//TODO 触发事件
RaiseServerException(null)
}
else
{
Session session = new Session(client)
lock (_clients)
{
_clients.Add(session)
_clientCount++
RaiseClientConnected(session)//触发客户端连接事件
}
session.RecvDataBuffer = new byte[client.ReceiveBufferSize]
//开始接受来自该客户端的数据
client.BeginReceive(session.RecvDataBuffer, 0, session.RecvDataBuffer.Length, SocketFlags.None,
new AsyncCallback(HandleDataReceived), session)
}
//接受下一个请求
server.BeginAccept(new AsyncCallback(HandleAcceptConnected), ar.AsyncState)
}
}
/// <summary>
/// 处理客户端数据
/// </summary>
///<param name="ar">
private void HandleDataReceived(IAsyncResult ar)
{
if (IsRunning)
{
Session session = (Session)ar.AsyncState
Socket client = session.ClientSocket
try
{
//如果两次开始了异步的接收,所以当客户端退出的时候
//会两次执行EndReceive
int recv = client.EndReceive(ar)
if (recv == 0)
{
//TODO 触发事件 (关闭客户端)
CloseSession(session)
RaiseNetError(session)
return
}
//TODO 处理已经读取的数据 ps:数据在session的RecvDataBuffer中
RaiseDataReceived(session)
//TODO 触发数据接收事件
}
catch (SocketException ex)
{
//TODO 异常处理
RaiseNetError(session)
}
finally
{
//继续接收来自来客户端的数据
client.BeginReceive(session.RecvDataBuffer, 0, session.RecvDataBuffer.Length, SocketFlags.None,
new AsyncCallback(HandleDataReceived), session)
}
}
}
#endregion
event_base_get_method函数能够获取对应的event_base使用的是哪个后端(即select、IOCP这些函数)。该函数返回一个字符串,字符串的内容就是select、poll、iocp这些后端的名字。 更正一下,由于在WIndows中,event_base_get_method函数返回的是win...欢迎分享,转载请注明来源:夏雨云
评论列表(0条)