最近服务器程序。用的socket api
只接受连接什么事都不做。发现一个问题。
服务器只能接受3900多个Client端再多了就Accept不了了。
开始怀疑是服务器程序写的有问题。
后来我打开本机的http服务和ftp服务。
模拟Client去连接80 或是 21端口发现还是3900快到4000左右的Client连接上后再有Client去连接就怎么也连接不上了。WSAGetLastError和GetLastError都得不到任何信息,真是奇怪。
难道是win2k的限制?我用的win2k adv svr 我又怀疑是硬件限制,我的计算机C4-1.8 512MB-ddr.
后来我在p4-2G 1GB-DDR SCSI-36G硬盘 win2k adv svr 上测试还是快到4000就再也连接不上了。系统换成Win2003 server还是这样。
哎···没折了。大伙遇到过这问题吗。帮帮忙吧。
问题点数:
200、回复次数:
32
1楼
matq2008 (
叶子.net)
回复于
2003-12-08 18:50:57 得分
10
俺从来没搞过这么大的用户数,一般在vc里listen最多是5,是同时的并发数,最多连接数是多少不知道
2楼
del_c_sharp (
武林中传说的摩托牛拉)
回复于
2003-12-08 19:32:26 得分
10
4000?的确不好发现,楼主是在实际项目中发现这个问题的,还是无意中测试发现的?
感觉和操作系统底层有关系,是否有可能是链路层的缓存环的问题?windows下是如何实现的
没有研究过。。。
3楼
Raptor (
猛禽)
回复于
2003-12-08 20:43:18 得分
10
好像是WIN的一个BUG,好像是改注册表一个什么地方可以,不过不记得了。
你试试看在线升级打上WIN的所有最新补丁看看。
7楼
TopCat (
令狐虫)
回复于
2003-12-08 22:13:53 得分
0
我也没试过这么大的并发连接数,不过我觉得一般并发数不太可能到达这么高,如果真这么高的话应该考虑做负载平衡,而不是想办法提高并发数吧。
8楼
RomanticProgrammer (
) 兰企鹅||南极俺最帅 ()
回复于
2003-12-08 23:36:33 得分
10
你用的是那种I/O模型;
Block?Asynchronize?Select?Overlapped?complition port?
每种I/O模型的性能表现(尤其连接数有很大的不同)。
从各种性能来看,完成端口的连接数最多。远远超过4000,(我忘了是多少了,明天给你个具体的数字)。
如果你要开发大型服务器,这几种模型约往后面性能越好,但实现也越复杂。
9楼
RomanticProgrammer (
) 兰企鹅||南极俺最帅 ()
回复于
2003-12-08 23:48:45 得分
0
socket服务器并非我们想象的那样简单,如果你要开发巨连接数,高性能的服务器,要在I/O模型上下功夫,并非只是简单的socket,bind,listen,accept。
在没有搞懂下面的函数之前,别指望你的服务器会有很高的性能(我曾经发现我的tcp服务器的性能和连接数根本和人家的游戏服务器没法相比,后来才发现原因就在这里)
ioctlsocket,WSAAsyncSelect,WSACreateEvent,WSAEventSelect,WSAWaitForMultipleEvents,CompletionROUTINE,CreateIoCompletionPort,GetQueuedCompletionStatus。。。。。
10楼
pp616 (
傻小子)
回复于
2003-12-08 23:50:07 得分
0
我用的IOCP 连接数始终都是4000不到差几十。怎么也增不上去啊。
MS 的 IIS应该用的IOCP吧。连接也是不到4000差几十。真奇怪??
11楼
ThinkX (
秋天的树)
回复于
2003-12-09 00:04:04 得分
10
IOCP是windows下大并发服务器的唯一选择。
按照你的说法,可能是配置的问题吧,不知道这个和硬件配置是否有关系,也许硬件不够强大。
13楼
RomanticProgrammer (
) 兰企鹅||南极俺最帅 ()
回复于
2003-12-09 12:10:30 得分
10
请说明您的tcp服务器使用的是什么io模型,我说的是socket I/O 模型!
一下是各种io模型的大概性能比较。
I/O 模型 尝试数/连接成功数
block: 7000/1008
noBlock: 7000/4011
WSAAsyncSelect: 7000/1956
WSAEventSelect: 7000/6999
Overlapped: 7000/5558
completion port: 7000/7000, 50000/4997
15楼
RomanticProgrammer (
) 兰企鹅||南极俺最帅 ()
回复于
2003-12-09 13:00:38 得分
10
更正:
completion port: 7000/7000, 50000/49997
16楼
warton (
知而后定 定而后动)
回复于
2003-12-09 13:16:46 得分
10
肯定是机器配置的问题了
另外操作系统也会有影响。
win2k adv也应该对连接有一个限制吧,以前在128M win2k pro版上测试过,几百个连接就不行了。
98好像只能支持100多个连接?用2000的数据中心试试:)
17楼
warton (
知而后定 定而后动)
回复于
2003-12-09 13:19:19 得分
10
512M的内存做为服务器来说是不是小了点?加内存应该就能提高连接数
要不做成集群,呵呵
18楼
warton (
知而后定 定而后动)
回复于
2003-12-09 13:29:53 得分
10
http://www.csdn.net/develop/article/22/22433.shtm
21楼
yesry (
噎死你)
回复于
2003-12-09 15:47:23 得分
10
我试过了,对于一台P4 1.8G ,256内存的机器CreateIoCompletionPort只能是3963个Socket可以连接!
22楼
warton (
知而后定 定而后动)
回复于
2003-12-09 16:31:47 得分
10
相信是硬件和操作系统的问题了。不过,如果是软件的问题,那我还是希望能有好有方法可以提高连接数。
23楼
RomanticProgrammer (
) 兰企鹅||南极俺最帅 ()
回复于
2003-12-09 17:17:23 得分
10
在你连接达到极限的时候看一下计算机的cpu使用率,内存使用,以及你的服务器所开启的线程。
如果你既然使用的完成端口模型,那从原理上来说,接受40000个连接没有问题(我做过测试)。如果你不能达到,情况有三:
1:计算机配置不够,主要是内存太小,建议512M以上。
2:cpu占有太高。
3:开启线程太多。
如果不是上面的问题,检查你的程序。
26楼
yesry (
噎死你)
回复于
2003-12-10 10:01:06 得分
10
我再一次试了,发现我错了,原来3963个Socket连接的限制是作为客户的Socket的缓冲区满,而不是作为服务器的Socket停止了。上次是因为我的客户端和服务器端在同一个机器上进行的,所以出现了缓冲区满的错误。
今天我用了3台客户端,各自连接了3996个Socket,也出现了缓冲区满的错误,但至少服务器可以接受11988个Socket连接。
27楼
RomanticProgrammer (
) 兰企鹅||南极俺最帅 ()
回复于
2003-12-10 10:19:28 得分
10
我想楼主的错误和上面的兄弟一样,是把客户端和服务端放在了同一台计算机上。而使创建的socket数超过了3997个造成的吧。
28楼
yesry (
噎死你)
回复于
2003-12-10 10:22:41 得分
10
另外,我想说一下对Completion Port 发表一下看法
其实,没有接触这个之前,我就已经产生了“任务—线程”的分配机制进行了深入的研究,自己开始做这个分配器,后来发现,它和ATL的COM的情况是一样的,有限个线程服务不确定个客户请求。由于这个分配器性能强差人意(时间就消耗在事件与事件发生者的对应查找上和动态列表增删中),我放弃了。现在突然发现可以用Completion Port来实现,嘿嘿,性能还不错。
所以上面提到的连接数目,我个人认为,在服务的任务忙得过来的情况下(比如楼主所说的除了accept外什么也不做),是否用Completion Port不会影响连接的数目。
29楼
copy_paste (
木石三)
回复于
2003-12-10 10:45:50 得分
10
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1410183
这边有介绍,需要是从注册表去改,不过没试过,:D