以下是Server的代码,最近在学习网络编程,一直在思考如何开发出高并发的服务器端。经常听说对服务器描述为同时10000个连接,就在想能否用C#写个这样的服务器出来呢。同步编程模型就不考虑了,来看看TcpListener的异步编程模型能否满足需求。
public partial class COMService { |
private int maxLink = 100000; |
private int currentLinked; |
private ManualResetEvent tcpClientConnected = new ManualResetEvent( false ); |
Thread thread = new Thread( new ParameterizedThreadStart(ShowStat)); |
thread.IsBackground = true ; |
TcpListener server = new TcpListener( new System.Net.IPEndPoint(0, 8090)); |
tcpClientConnected.Reset(); |
IAsyncResult result = server.BeginAcceptTcpClient( new AsyncCallback(Acceptor), server); |
tcpClientConnected.WaitOne(); |
private void ShowStat( object o) { |
lock ( typeof (COMService)) { |
Console.WriteLine( "当前连接数:" + currentLinked + "/" + maxLink); |
private void Acceptor(IAsyncResult o) { |
TcpListener server = o.AsyncState as TcpListener; |
Debug.Assert(server != null ); |
client = server.EndAcceptTcpClient(o); |
System.Threading.Interlocked.Increment( ref currentLinked); |
IAsyncResult result = server.BeginAcceptTcpClient( new AsyncCallback(Acceptor), server); |
Thread.CurrentThread.Join(); |
private void Close(TcpClient client) { |
client.Client.Shutdown(SocketShutdown.Both); |
System.Threading.Interlocked.Decrement( ref currentLinked); |
以下是Client的代码:
public class ClientPool { |
private static List<TcpWork> clients = new List<TcpWork>(); |
private static int freeCount; |
private static int workCount; |
private static int maxAllowed = 2; |
private static int minClients = 2; |
private static ClientPool instance; |
private static readonly object syncInstanceObj = new object (); |
public static ClientPool Singleton { |
instance = new ClientPool(); |
private static readonly object syncObj = new object (); |
public TcpWork GetClient() { |
TcpWork work = new TcpWork(); |
work.Connect( "127.0.0.1" , 8090); |
work.LingerState = new LingerOption( false , 3); |
Console.WriteLine(workCount); |
Console.WriteLine(ex.Message); |
Client模拟多线程并发:
static void Main( string [] args) { |
for ( int i = 0; i < 1000; i++) { |
ThreadPool.QueueUserWorkItem( new WaitCallback(Work), null ); |
private static void Work( object o) { |
ClientPool.Singleton.GetClient(); |
从这个编程模型可以看出,高并发的服务器不光需要满足有多少个并发连接数,每秒创建多少个连接数也是个重要指标~~
实际运行上看看,TcpListener每秒大概能创建两个连接,其他的连接会被拒绝,保持的长连接数1000的样子。很明显,TcpListener要被咔嚓掉了~~
注意,以上代码仅仅是用来测·试连接用的,这种写法会导致服务器端的连接无法释放~~~~