开发高性能的Socket服务器

要编写高性能的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);

}

}

你可能感兴趣的:(socket)