public
class
NET_Server : IDisposable
{
private
bool
IsDisponse
=
false
;
~
NET_Server()
{
this
.Dispose(
false
);
}
public
void
Dispose()
{
Dispose(
true
);
GC.SuppressFinalize(
this
);
//
请求系统不要调用指定对象的终结器
}
protected
virtual
void
Dispose(
bool
disponse)
{
if
(
!
IsDisponse)
{
try
{
this
._ServerRun
=
false
;
foreach
(DictionaryEntry client
in
ClientsTable)
{
((Socket)client.Value).Shutdown(SocketShutdown.Both);
}
this
.Server.Close();
this
.ClientsTable.Clear();
clientpool.poolClear();
}
catch
{ }
IsDisponse
=
true
;
}
}
private
Socket Server
=
null
;
private
BufferManager Buffer;
private
SocketAsyncEventArgsPool RWpool;
//
.net 3.5异步socket的关键
private
IPEndPoint _iep;
private
int
Max_Recv_Buff_Size
=
1024
;
private
int
Max_Connected_Count
=
512
;
private
halfbuffpool clientpool;
public
NET_Server(
string
ipsrc,
int
port)
{
_iep
=
new
IPEndPoint(IPAddress.Parse(ipsrc), port);
this
.ClientsTable
=
new
Hashtable();
clientpool
=
new
halfbuffpool();
//
管理客户端的一个数组对象
}
public
NET_Server(
string
ipsrc,
int
port,
int
nconn,
int
nbuff)
{
//
初始化
this
.Max_Recv_Buff_Size
=
nbuff;
this
.Max_Connected_Count
=
nconn;
_iep
=
new
IPEndPoint(IPAddress.Parse(ipsrc), port);
this
.ClientsTable
=
new
Hashtable();
clientpool
=
new
halfbuffpool();
}
//
数据收发的超时时间
private
int
_RecvOutTime
=
3000
;
public
int
RecvTimeout {
get
{
return
_RecvOutTime; }
set
{ _RecvOutTime
=
value; } }
private
int
_SendTimeout
=
1000
;
public
int
SendTimeout {
get
{
return
_SendTimeout; }
set
{ _SendTimeout
=
value; } }
public
event
ServerEventHandler Notification;
//
开启服务器
public
bool
StartServer()
{
this
._ServerRun
=
true
;
this
.Server
=
new
Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
bool
result
=
false
;
if
(IsDisponse)
{
throw
new
ObjectDisposedException(
"
Server is Disponse!
"
);
}
try
{
//
设定与服务器相关参数
this
.Server.Bind(
this
._iep);
this
.Server.Listen(
5
);
this
.Server.SendTimeout
=
this
._SendTimeout;
this
.Server.ReceiveTimeout
=
this
._RecvOutTime;
result
=
true
;
//
创建并初始化缓冲区管理对象
Buffer
=
new
BufferManager(
this
.Max_Connected_Count
*
this
.Max_Recv_Buff_Size,
this
.Max_Recv_Buff_Size);
Buffer.Inint();
//
构造SocketAsyncEventArgs池
RWpool
=
new
SocketAsyncEventArgsPool(
this
.Max_Connected_Count);
for
(
int
i
=
0
; i
<
this
.Max_Connected_Count;i
++
)
{
SocketAsyncEventArgs asyniar
=
new
SocketAsyncEventArgs();
asyniar.Completed
+=
new
EventHandler
<
SocketAsyncEventArgs
>
(Asyn_Completed);
RWpool.Push(asyniar);
}
Console.WriteLine(
"
Begin Listen....
"
);
Accept();
}
catch
(Exception ex) { Notification(
null
,
new
ServerEventArgs(ArgsType.EXCEPTION, ex.Message,
null
));}
return
result;
}
private
void
Accept()
//
开始接受连接
{
if
(
!
_ServerRun)
return
;
if
(RWpool.Count
>
0
)
{
SocketAsyncEventArgs asyniar
=
RWpool.Pop();
if
(
!
Server.AcceptAsync(asyniar))
//
弹出一个SocketAsyncEventArgs对象开始AcceptAsyn
{
BeginAccep(asyniar);
//
如果I/O挂起等待异步则触发AcceptAsyn_Asyn_Completed事件
//
此时I/O操作同步完成,不会触发Asyn_Completed事件,所以指定BeginAccept()方法
}
}
else
{
Console.WriteLine(
"
Had Max Connected!
"
);
}
}
private
Hashtable ClientsTable;
private
void
BeginAccep(SocketAsyncEventArgs e)
{
try
{
if
(e.SocketError
==
SocketError.Success)
{
string
clientip
=
string
.Format(
"
{0}
"
,((IPEndPoint)e.AcceptSocket.RemoteEndPoint).Address);
if
(ClientsTable.Contains(clientip))
{
e.AcceptSocket.Shutdown(SocketShutdown.Both);
e.AcceptSocket
=
null
;
//
保持SocketAsynEventArgs池 的堆栈平衡
RWpool.Push(e);
return
;
}
else
this
.ClientsTable.Add(clientip, e.AcceptSocket);
Notification(
null
,
new
ServerEventArgs(ArgsType.CLIENTCONN, clientip,
null
));
//
查找客户如果不存在,则添加一个新客户
halfbuff client
=
clientpool.GetClient((IPEndPoint)e.AcceptSocket.RemoteEndPoint);
if
(client
==
null
)
{
client
=
new
halfbuff((IPEndPoint)e.AcceptSocket.RemoteEndPoint);
client.HalfEvent
+=
new
EventHandler
<
HaflBuffEventArgs
>
(OnHalfEvent);
clientpool.poolAdd(client);
}
clientpool.poolAdd(client);
//
接受一个连接,发送欢迎信息
e.AcceptSocket.Send(Encoding.ASCII.GetBytes(
"
send
"
));
if
(Buffer.SetBuffer(e))
{
if
(
!
e.AcceptSocket.ReceiveAsync(e))
//
是否触发 Asyn_Commpleted事件
{
BeginReceive(e);
}
}
}
else
{
e.AcceptSocket
=
null
;
//
保持SocketAsynEventArgs池 的堆栈平衡
RWpool.Push(e);
Console.WriteLine(
"
Not Accept!
"
);
}
}
catch
(Exception ex){
e.AcceptSocket
=
null
;
//
保持SocketAsynEventArgs池 的堆栈平衡
RWpool.Push(e);
Notification(
null
,
new
ServerEventArgs(ArgsType.EXCEPTION, ex.Message,
null
));
}
finally
{
Accept();
}
}
private
void
OnHalfEvent(
object
sender,HaflBuffEventArgs e)
{
Notification(
null
,
new
ServerEventArgs(ArgsType.RECEIVE,
""
, e.BUFF));
}
private
bool
_debug
=
false
;
public
bool
Debug {
get
{
return
_debug; }
set
{ _debug
=
value; } }
private
void
BeginReceive(SocketAsyncEventArgs e)
{
halfbuff client
=
clientpool.GetClient((IPEndPoint)e.AcceptSocket.RemoteEndPoint);
if
(e.SocketError
==
SocketError.Success
&&
e.BytesTransferred
>
0
)
{
byte
[] data
=
new
byte
[e.BytesTransferred];
Array.Copy(e.Buffer, e.Offset, data,
0
, data.Length);
//
从e.Buffer块中复制数据出来,保证它可重用
if
(_debug)
Notification(
null
,
new
ServerEventArgs(ArgsType.DEBUG,
"
debug
"
,data));
if
(data.Length
>
3
)
//
排除心跳包 01
{
if
(client
!=
null
)
client.pool.Enqueue(data);
}
if
(
!
e.AcceptSocket.ReceiveAsync(e))
{
BeginReceive(e);
//
}
}
else
{
string
clientip
=
string
.Format(
"
{0}
"
,((IPEndPoint)e.AcceptSocket.RemoteEndPoint).Address);
this
.ClientsTable.Remove(clientip);
Console.WriteLine(
"
A Client Disconnected,{0}
"
,e.AcceptSocket.RemoteEndPoint);
Notification(
null
,
new
ServerEventArgs(ArgsType.CLIENTDISCONN, clientip,
null
));
//
查找客户存在,则删除客户
if
(client
!=
null
)
{
//
e.AcceptSocket.Shutdown(SocketShutdown.Both);
clientpool.poolDel(client);
}
e.AcceptSocket
=
null
;
Buffer.FreeBuffer(e);
RWpool.Push(e);
if
(RWpool.Count
==
1
)
{
Accept();
}
}
}
private
void
Asyn_Completed(
object
sender, SocketAsyncEventArgs e)
{
switch
(e.LastOperation)
{
case
SocketAsyncOperation.Accept:
BeginAccep(e);
break
;
case
SocketAsyncOperation.Receive:
BeginReceive(e);
break
;
}
}
private
bool
_ServerRun
=
true
;
public
bool
ServerRun {
get
{
return
_ServerRun; }
set
{ _ServerRun
=
value; } }
public
void
StopServer()
{
this
._ServerRun
=
false
;
foreach
(DictionaryEntry client
in
ClientsTable)
{
((Socket)client.Value).Shutdown(SocketShutdown.Both);
}
if
(
this
.Server
!=
null
)
this
.Server.Close();
this
.ClientsTable.Clear();
Console.WriteLine(
"
The Server Stoped!
"
);
}
}