关于使用完成端口的高并发SOCKET编程问题,请高手指教
最近因为工作需要,搜到了一篇CSDN上关于使用完成端口的高性能并发SOCKET编程文章,与工作相似的是,我确实需要处理大量客户端长链接的问题,一般来说一个客户端链接后会长期在线。我一直没做压力测试,不知道在大量客户端(5000个客户端是我的设计目标)申请连接时,是否可以链接以及连接后是否可以正常工作。而这个完成端口早就听说了,据说是专为解决大量并发而产生的。然而根据我初步阅读其代码,发现核心思想貌似是使用异步连接和信号量技术来处理来自客户端的链接。我首先想请教用过完成端口的达人,在完成端口技术中,如果同时维持5000个客户端在线,服务器是否实实在在的开销了5000个SOCKET。
其次,当服务器真的链接5000个客户端并实实在在的开销了5000个SOCKET时(或者若干SOCKET),如何计算每个SOCKET获得的理论带宽(以千兆网卡为例)。这与不使用完成端口技术获得5000个客户连接(假如可以的话)相比,在网络带宽上是否有优势?如果用异步的BeginAccept加上内存映射表和多线程技术来处理多客户端链接,与用完成端口技术来实现,到底有多大的差异呢?
由于还没有搞清楚完成端口的原来和使用流程,在这里把我的大概处理方法说明如下,注意这是没有经过压力测试的,我还真不知道5000个(或者1000个)客户端申请连接会是什么效果:
1. 程序主进程开启LISTEN
Server.Listen(5000);
注意,这个 Listen(5000)同样出现在了上文提到的完成端口技术的博文中,大家可以看他的代码
2. //** 启动接收监听线程
td = new Thread(new ThreadStart(DoListen));
td.Start();
3. 线程启动函数中这样处理:
Server.BeginAccept(new AsyncCallback(MyAccept), null);
4. 一旦有客户端连接请求,则回调函数 MyAccept中创建客户端线程
//** 在原始套接字上调用EndAccept返回新的套接字
Socket client = Server.EndAccept(iar);
//** 收到连接,查IP表,如果已有连接,则断掉以前的,然后重新创建
IPEndPoint clientpoint = client.RemoteEndPoint as IPEndPoint;
其中关键就是非阻塞方式调用BeginAccept和在原始SOCKET上用EndAccept去生成新的SOCKET,这个SOCKET被分配给客户端连接并会在一个记录客户端IP和SOCKET的映射表中得到反映。以后一旦有发送数据的需求,则根据客户端的IP查找对应的SOCKET。
到了这里,我最疑惑的问题就是上面提到的,当5000个客户端链接请求时,使用完成端口技术的方法是否和我这个方法一样,让服务器实实在在的付出了5000个SOCKET的代价,如果真是这样,那完成端口的优势在哪里?
顺便说一下,我的程序指导思想也是异步全双工处理客户端链接,上下(收发)由2个线程处理,走同一个SOCKET(一个客户端一个SOCKET)