C# Socket 编程之 TcpListener

 

以下是Server的代码,最近在学习网络编程,一直在思考如何开发出高并发的服务器端。经常听说对服务器描述为同时10000个连接,就在想能否用C#写个这样的服务器出来呢。同步编程模型就不考虑了,来看看TcpListener的异步编程模型能否满足需求。

 

	public partial class COMService {
		private int maxLink = 100000;
		private int currentLinked;
      private ManualResetEvent tcpClientConnected = new ManualResetEvent(false);
		public void Start() {

			Thread thread = new Thread(new ParameterizedThreadStart(ShowStat));
			thread.IsBackground = true;
			thread.Start();
			
			TcpListener server = new TcpListener(new System.Net.IPEndPoint(0, 8090));
			server.Start(100);
			tcpClientConnected.Reset();
			IAsyncResult result = server.BeginAcceptTcpClient(new AsyncCallback(Acceptor), server);
			tcpClientConnected.WaitOne();
		}

		private void ShowStat(object o) {
			while (true) {
				lock (typeof(COMService)) {
					Console.WriteLine("当前连接数:" + currentLinked + "/" + maxLink);
				}
				Thread.Sleep(2000);
			}
		}

		private void Acceptor(IAsyncResult o) {
			TcpListener server = o.AsyncState as TcpListener;
			Debug.Assert(server != null);
			TcpClient client = null;
			try {
				client = server.EndAcceptTcpClient(o);
				System.Threading.Interlocked.Increment(ref currentLinked);
				
			} catch {
				
			}
			IAsyncResult result = server.BeginAcceptTcpClient(new AsyncCallback(Acceptor), server);
			if (client == null) {
				return;
			} else {
				Thread.CurrentThread.Join();
			}
			Close(client);
		}

		private void Close(TcpClient client) {
			if (client.Connected) {
				client.Client.Shutdown(SocketShutdown.Both);
			}
			client.Client.Close();
			client.Close();

			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;
		/// <summary>
		/// create new instance
		/// </summary>
		private ClientPool() {
		}

		private static ClientPool instance;
		private static readonly object syncInstanceObj = new object();
		public static ClientPool Singleton {
			get {
				if (instance == null) {
					lock (syncInstanceObj) {
						if (instance == null) {
							instance = new ClientPool();
						}
					}
				}
				return instance;
			}
		}

		private static readonly object syncObj = new object();

		public TcpWork GetClient() {
				try {
				TcpWork work = new TcpWork();
				work.Connect("127.0.0.1", 8090);
				work.LingerState = new LingerOption(false, 3);
				work.IsWork = true;
				work.Expired = false;
				workCount++;
				lock (syncObj) {
					clients.Add(work);
				}
				Console.WriteLine(workCount);
				return work;
			} catch (Exception ex){
				Console.WriteLine(ex.Message);
				return null;
			}
		}
	}
Client模拟多线程并发:

	class Program {
		static void Main(string[] args) {
			for (int i = 0; i < 1000; i++) {
				ThreadPool.QueueUserWorkItem(new WaitCallback(Work), null);
			}
			Console.ReadKey();
		}

		private static void Work(object o) {
			ClientPool.Singleton.GetClient();
		}
	}

 

从这个编程模型可以看出,高并发的服务器不光需要满足有多少个并发连接数,每秒创建多少个连接数也是个重要指标~~

 

实际运行上看看,TcpListener每秒大概能创建两个连接,其他的连接会被拒绝,保持的长连接数1000的样子。很明显,TcpListener要被咔嚓掉了~~

 

注意,以上代码仅仅是用来测·试连接用的,这种写法会导致服务器端的连接无法释放~~~~

 

posted @ 2010-12-17 15:59 Birdshover 阅读(...) 评论(...) 编辑 收藏