using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace SocketServer
{
/// <summary>
/// 监听端口,接受多客户的TCP连接
/// </summary>
public class TcpServer
{
/// <summary>
/// 网络通讯事件模型委托
/// </summary>
/// <param name="sender"></param>
/// <param name="e">与客户端的连接类</param>
public delegate void NetEvent(object sender, TcpClient e);
#region 事件定义
/// <summary>
/// 客户端连接成功事件
/// </summary>
public event NetEvent Connected;
/// <summary>
/// 客户端断开连接事件
/// </summary>
public event NetEvent DisConnection;
/// <summary>
/// 接收到数据事件
/// </summary>
public event NetEvent Reviced;
#endregion
#region 字段
private int maxClients = 10000; //最大客户连接数
private IPEndPoint iep; //监听终结点
private TcpListener listener; //监听类
private Dictionary<EndPoint, TcpClient> session;
#endregion
#region 属性
/// <summary>
/// 当前客户连接数
/// </summary>
public int CurrentClients
{
get { return session.Count; }
}
/// <summary>
/// 与客户连接的所有TcpClient
/// </summary>
public Dictionary<EndPoint, TcpClient> Session
{
get { return session; }
}
#endregion
#region 构造函数
/// <summary>
/// 构造函数
/// </summary>
/// <param name="port">监听的端口号</param>
/// <param name="maxClient">最大客户连接量</param>
public TcpServer(int port, int maxClients, string IP)
{
iep = new IPEndPoint(IPAddress.Parse(IP), port);
this.maxClients = maxClients;
}
public TcpServer(int port)
{
iep = new IPEndPoint(IPAddress.Parse("0.0.0.0"), port);
}
#endregion
#region 公用方法
/// <summary>
/// 启动服务器程序,开始监听客户端请求
/// </summary>
public void Start()
{
session = new Dictionary<EndPoint, TcpClient>();
listener = new TcpListener(iep);
listener.Start(1);
//监听客户端连接请求
listener.BeginAcceptTcpClient(
new AsyncCallback(TcpClientConnection), listener);
}
public void TcpClientConnection(IAsyncResult ar)
{
//接受客户的连接,得到网络流
TcpClient client = listener.EndAcceptTcpClient(ar);
NetworkStream netStream = client.GetStream();
//保存在线session
if (session.ContainsKey(client.Client.RemoteEndPoint))
{
session[client.Client.RemoteEndPoint] = client;
}
else
{
session.Add(client.Client.RemoteEndPoint, client);
}
if (CurrentClients < maxClients)
{
//继续监听客户端连接请求
listener.BeginAcceptTcpClient(
new AsyncCallback(TcpClientConnection), listener);
}
else
{ //达到最大连接客户数,则关闭监听.
listener.Stop();
}
//客户端连接成功事件
if (Connected != null) Connected(this, client);
//开始接受数据
netStream.BeginRead(new byte[0], 0, 0,
new AsyncCallback(RevieData), client);
#region 启用多线程接收数据(连接数受线程数限制)
//Thread tListen = new Thread(delegate()
// {
// bool connected = true;
// while (connected)
// {
// if (client.Available > 0)
// {
// if (netStream.CanRead)
// {
// byte[] bytes = new byte[client.Available];
// netStream.Read(bytes, 0, client.Available);
// //触发接收到数据事件
// if (Reviced != null) { Reviced(bytes, client); }
// }
// }
// else
// {
// try
// {
// if (netStream.CanWrite)
// {
// Thread.Sleep(50);
// //client.Client.Send(new Byte[] { });
// netStream.Write(new byte[] { }, 0, 0);
// }
// }
// catch
// {
// connected = false;
// session.Remove(client.Client.RemoteEndPoint);
// }
// }
// }
// //Console.WriteLine("This client is disconnection" + client.Client.RemoteEndPoint.ToString());
// //触发断开连接事件
// if (DisConnection != null) { DisConnection(this, client); }
// }
//);
//tListen.Start();
#endregion
}
/// <summary>
/// 接收数据
/// </summary>
/// <param name="ar"></param>
public void RevieData(IAsyncResult ar)
{
TcpClient client = (TcpClient)ar.AsyncState;
NetworkStream netStream = client.GetStream();
try
{
int revieLen = client.Available;
byte[] bytes = new byte[revieLen];
netStream.BeginRead(bytes, 0, revieLen,
new AsyncCallback(RevieData), client);
//触发接收到数据事件
if (Reviced != null) { Reviced(bytes, client); }
}
catch //Socket被关闭,连接断开
{
//如果已关闭侦听器,则打开,继续监听
if (CurrentClients >= maxClients)
{
listener.Start(1);
listener.BeginAcceptTcpClient(
new AsyncCallback(TcpClientConnection), listener);
}
session.Remove(client.Client.RemoteEndPoint);
//触发客户断开事件
if (DisConnection != null) { DisConnection(this, client); }
}
}
#endregion
}
}