开发高性能的Socket服务器
2011-10-29 10:45
169 查看
要编写高性能的Socket服务器,为每个接收的Socket分配独立的处理线程的做法是不可取的,当连接数量很庞大时,服务器根本无法应付。要响应庞大的连接数量,需要使用IOCP(完成端口)来撤换并处理响应。
.net framework的System.Net.Sockets.Socket 类有一组xxxAsync方法是封装了IOCP的处理,用于编写高性能Socket应用程序,xxxAsync该组方法需要结合SocketAsyncEventArgs类来使用,下面是MSDN参考资料,里面有一个详细的例子:
http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socketasynceventargs.aspx
Socket类xxxAsync的方法,使用起来比较复杂,需要时间消化上述的例子,结合实际编写所需的操作。
以下是使用SocketAsyncEventArgs时应该注意的地方:
1.连接和接收时不要使用一个SocketAsyncEventArgs对象,如下面代码,accept和receive是不同的对象,不用使用同一个SocketAsyncEventArgs调用AcceptAsync和ReceiveAsync方法。
SocketAsyncEventArgs
accept = _RequestPool.PopOrNew();
bool raise = _Listener.AcceptAsync(accept);
…
SocketAsyncEventArgs
receive = _RequestPool.PopOrNew();
receive.SetBuffer(http.ReceiveBuffer, 0, http.ReceiveBuffer.Length);
bool raise = http.Socket.ReceiveAsync(receive);
2.应该使用可伸缩的SocketAsyncEventArgsPool连接池缓存,如下面的PopOrNew方法,其他数据缓存类似。
class
SocketAsyncEventArgsPool
{
Stack<SocketAsyncEventArgs> _Pool;
public SocketAsyncEventArgsPool()
{
_Pool =
new Stack<SocketAsyncEventArgs>();
}
public
void Push(SocketAsyncEventArgs item)
{
if (item ==
null) return;
lock (_Pool)
{
_Pool.Push(item);
}
}
public
SocketAsyncEventArgs PopOrNew()
{
if (Count == 0)
return
new SocketAsyncEventArgs();
return Pop();
}
public
SocketAsyncEventArgs Pop()
{
lock (_Pool)
{
return _Pool.Pop();
}
}
public
int Count
{
get {
return _Pool.Count; }
}
public
void Clear()
{
while (Count > 0)
{
Pop().Dispose();
}
}
}
3.当接收到长度为0的数据时,表明客户端关闭Socket,这时应该开始执行服务端的Socket关闭操作。
private
void OnReceive(SocketAsyncEventArgs receive)
{
try
{
if (receive.SocketError ==
SocketError.Success && receive.BytesTransferred > 0)
{
//处理接收
…
}
else
{
Close(receive);
//关闭Socket
}
}
catch (Exception ex)
{
TraceError(ex);
}
}
.net framework的System.Net.Sockets.Socket 类有一组xxxAsync方法是封装了IOCP的处理,用于编写高性能Socket应用程序,xxxAsync该组方法需要结合SocketAsyncEventArgs类来使用,下面是MSDN参考资料,里面有一个详细的例子:
http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socketasynceventargs.aspx
Socket类xxxAsync的方法,使用起来比较复杂,需要时间消化上述的例子,结合实际编写所需的操作。
以下是使用SocketAsyncEventArgs时应该注意的地方:
1.连接和接收时不要使用一个SocketAsyncEventArgs对象,如下面代码,accept和receive是不同的对象,不用使用同一个SocketAsyncEventArgs调用AcceptAsync和ReceiveAsync方法。
SocketAsyncEventArgs
accept = _RequestPool.PopOrNew();
bool raise = _Listener.AcceptAsync(accept);
…
SocketAsyncEventArgs
receive = _RequestPool.PopOrNew();
receive.SetBuffer(http.ReceiveBuffer, 0, http.ReceiveBuffer.Length);
bool raise = http.Socket.ReceiveAsync(receive);
2.应该使用可伸缩的SocketAsyncEventArgsPool连接池缓存,如下面的PopOrNew方法,其他数据缓存类似。
class
SocketAsyncEventArgsPool
{
Stack<SocketAsyncEventArgs> _Pool;
public SocketAsyncEventArgsPool()
{
_Pool =
new Stack<SocketAsyncEventArgs>();
}
public
void Push(SocketAsyncEventArgs item)
{
if (item ==
null) return;
lock (_Pool)
{
_Pool.Push(item);
}
}
public
SocketAsyncEventArgs PopOrNew()
{
if (Count == 0)
return
new SocketAsyncEventArgs();
return Pop();
}
public
SocketAsyncEventArgs Pop()
{
lock (_Pool)
{
return _Pool.Pop();
}
}
public
int Count
{
get {
return _Pool.Count; }
}
public
void Clear()
{
while (Count > 0)
{
Pop().Dispose();
}
}
}
3.当接收到长度为0的数据时,表明客户端关闭Socket,这时应该开始执行服务端的Socket关闭操作。
private
void OnReceive(SocketAsyncEventArgs receive)
{
try
{
if (receive.SocketError ==
SocketError.Success && receive.BytesTransferred > 0)
{
//处理接收
…
}
else
{
Close(receive);
//关闭Socket
}
}
catch (Exception ex)
{
TraceError(ex);
}
}
相关文章推荐
- Workerman 一款纯PHP开发的开源高性能的PHP socket 服务器框架。
- 高性能Socket服务器的开发需要注意事项
- 高性能Socket服务器的开发需要注意事项
- 开发高性能的Socket服务器
- (转)详谈高性能TCP服务器开发
- Linux 高性能服务器编程——socket选项
- 高性能Socket服务器编程-02
- 【高性能web开发】 ASP.NET Web服务器 (一)
- 【高性能web开发】 ASP.NET Web服务器
- 高性能服务器开发
- workerman高性能socket服务器框架搭建
- 服务器后端开发系列——《实战Nginx高性能Web服务器》 (转载)
- 使用 kqueue 在 FreeBSD 上开发高性能应用服务器
- GCDAsyncSocket不通过服务器进行客户端间直接连接—iOS移动开发
- C++教程网 大并发高性能高可用可伸缩性服务器开发无KEY
- 高性能服务器软件开发
- Netty Java NIO 高性能Socket 开发框架
- Linux 高性能服务器编程——socket选项
- [Socket]基于C++的纯面向对象的通用高性能大并发TCP-SERVER/CLIENT开发框架
- 高性能Socket服务器编程-01