本文转载自:
https://www.cnblogs.com/birdshover/archive/2010/12/17/1909375.html 作者:birdshover 转载请注明该声明。
Client模拟多线程并发:
以下是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;
}
}
}
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要被咔嚓掉了~~
注意,以上代码仅仅是用来测·试连接用的,这种写法会导致服务器端的连接无法释放~~~~