刚刚做socket通讯,最多同时连接200个左右的socket使用什么I/O模型最好!!!提供示例者加分!!!
解决方案 »
- 用WebBrowser控件打开PowerPoint后, 怎么让它翻页(自己设定的,比如一秒或多少时间一页)
- 向桌面贴图的问题
- 服务程序以管理员身份启动一个进程,被启动进程要能与桌面交互
- 一个对话框的按钮与位图的问题,请帮忙解决,在线等,谢谢!!
- 大家好!小弟有个关于sql的小问题?
- 用MFC做Activex控件,如何实现里头的Picture Control跟随控件的大小而改变?
- MFC 在未装word的电脑上如何把数据库中的数据写成.doc格式.
- 绘图的基本概念!!!非常急!!
- 大头菜再问:COM的方法定义问题?
- run time check failure #0
- 高手请进,共同讨论:为Shell 添加加速键(Accelerator)
- 学习 visual c++ 6.0好的方
200个就上IOCP,真是大材小用
不要小看这个,假如是IOCP涉及的知识很多很多,线程池、内存等等。
处理器: AMD3000+
内存: 1GB
硬盘: 80GB
网络: 100MB 局域网
网络模型: 重叠IO连接数量 = 51000
*******************************************************************************
现在使用重叠I/O来实现,在2M的adsl上网的机器做服务器最大连接数是多少才能发挥最好的性能!!!答:这取决与网络数据的交互量,得根据交互量来计算。****************************************************************************
不要小看这个,假如是IOCP涉及的知识很多很多,线程池、内存等等。答: 重叠IO要想做好同样涉及和多知识,线程池、内存池等等。
处理器: AMD3000+
内存: 1GB
硬盘: 80GB
网络: 100MB 局域网
网络模型: 重叠IO连接数量 = 51000
---------------------------------------------------------
我没看走眼吧,51000个连接,1GB内存? 你不会光连接然后什么都不做吧?
51000 ,算你每一个连接平均缓冲只用4KB,51000*4KB=?,SOCKET本身缓冲R+W是多少?
windows 32位系统能分配多少空闲物理内存资源给SOCKET? 不会超过50%吧,能上51000?
严重怀疑你这51000连接的意义,操作系统竟然还 XP,我不知道你是怎么测试的,
一个WIN32进程,就算你开启大内存支持,也最多能使用3GB虚拟内存
开51000个连接,不管你什么模型,除非连了就断,否则
根本就是在扯淡
一个WIN32进程,就算你开启大内存支持,也最多能使用3GB虚拟内存
开51000个连接,不管你什么模型,除非连了就断,否则
根本就是在扯淡
答: 我还真就是 xp 的(关于内存我上面说过了), 而且客户端连接上以后没有断开。另外告诉你我这个不是在扯淡。
我自己写了一整套服务器软件和配套软件,
使用过线程池模型,IOCP模型,SELECT模型,到最后自己开发的非阻塞模型
我做过这种带数据的测试,我可以负责任的告诉你,WIN32系统下,带数据收发的正常服务,不可能达到这个数字的
上面确实是我计算错误,我算成2GB了,这个SORRY
我的4KB指的是每个连接的缓冲大小,按每个连接你只分配4KB
51000*4KB,200000KB,大约200M
那SOCKET R+W需要多少? 至少4+4KB吧,去掉400M,正好在这个极限内核分配内,别的不说,系统资源已经基本吃掉一大半,如果一个WIN32服务器软件,什么都不做,就一些连接要干掉这么多,你认为有意义吗?
XP系统里,有个限制,我想你应该知道,虽然你连接了这么多,但是实际上,大部分都是假死状态的,有一些还处于等待队列,最新版本XP系统SP补丁下,即使你修改TCP参数,也没用,连接是假死的,你的测试得到了连接成功,实际上根本没有连接完成或者被挂起了,相当部分还需要服务器端从等待队列到内存的过程,但是你没有进行数据收发操作,你无从知道是真连接还是假连接我建议你再做个测试,不管什么模型,使用WINSOCK 2。2,服务器端只LISTEN,队列设置为MAX,
不执行ACCEPT,你再测试能成功连接的个数是多少?是不是很吓人,速度太快了,服务器端什么都不做,客户端就能连接成功这么多!! 你就会发现你的实现是不是正确。
这个连接的速度实际上和什么模型根本没关系,因为它只是操作系统的等待队列,
握手是IP层是事情,我们根本还来不及也无法进行参与,
所以你做的测试==......
我自己写了一整套服务器软件和配套软件,
使用过线程池模型,IOCP模型,SELECT模型,到最后自己开发的非阻塞模型
我做过这种带数据的测试,我可以负责任的告诉你,WIN32系统下,带数据收发的正常服务,不可能达到这个数字的答: 带数据的测试我也做过,我也可以负责任的告诉你,最初我没有使用1G内存的时候(512MB)我达到了32300,而且个客户端连接以后都发送数据给服务器,服务器也去接收了,这也是经过我实际测试的,我不知道你是怎么做的居然达不到这个数量。******************************************************************
XP系统里,有个限制,我想你应该知道,虽然你连接了这么多,但是实际上,大部分都是假死状态的,有一些还处于等待队列,最新版本XP系统SP补丁下,即使你修改TCP参数,也没用,连接是假死的,你的测试得到了连接成功,实际上根本没有连接完成或者被挂起了,相当部分还需要服务器端从等待队列到内存的过程,但是你没有进行数据收发操作,你无从知道是真连接还是假连接答: 在本次恢复的最上面我已经回答了。*********************************************************************************8
那SOCKET R+W需要多少? 至少4+4KB吧,去掉400M,正好在这个极限内核分配内,别的不说,系统资源已经基本吃掉一大半,如果一个WIN32服务器软件,什么都不做,就一些连接要干掉这么多,你认为有意义吗?你说这话的时候经过成熟的思考吗? 1G可以达到 51000,按你所说去掉 400MB 还剩多少呢?如果2G内存呢(在64位机上内存可以更大)? 你说这没有意义我感觉很奇怪,在一些环境下是需要这种大量连接数的,比如客户端要连接到一个服务器并且大部分的时间是空闲的,因为他们是否要接收数据取决于服务器是否有他们的数据(简单的例子,服务器是广告服务器,也就是说当要有广告的时候服务器才发送给客户户端,当没有广告示保持空闲,这只是一个例子,当然可以不这么做,但怎么做取决于具体产品的构架)******************************************************************************我建议你再做个测试,不管什么模型,使用WINSOCK 2。2,服务器端只LISTEN,队列设置为MAX,
不执行ACCEPT,你再测试能成功连接的个数是多少?是不是很吓人,速度太快了,服务器端什么都不做,客户端就能连接成功这么多!! 你就会发现你的实现是不是正确。
答: 如果你真的不信我可以把我的测试代码发给大家,大家搭建环境测试一下,看看我是不是在扯淡,有要得请举手。
最后我可以对我所说的每一句话负责。
这个连接的速度实际上和什么模型根本没关系,因为它只是操作系统的等待队列,
握手是IP层是事情,我们根本还来不及也无法进行参与,*************************************************************************
连接的速度和系统能够接受的连接数量是两个概念,当连接建立后是放到成功连接队列里的,等待队列中的元素应用层是无法发现的,只用党连接进入成功连接队列中,应用层的accept才会返回。
我只是希望你按我说的方法,自己再做个测试,不要在服务器端ACCEPT,看能成功连接多少个,花费多少时间,
和你原来采用的模型对比,速度有什么差距,连接数有什么差距
因为你从客户端连接上看,确实成功了,但是关键的一步就在那里,你的CONNECT返回成功,实际上你的连接还没有完全完成,只是躺在系统的等待队列里面,这就是区别
已经告诉你了,
那个是等待队列的速度和连接数,而不是什么模型的速度和连接数,从根本上就是没有意义的。
我只是希望你按我说的方法,自己再做个测试,不要在服务器端ACCEPT,看能成功连接多少个,花费多少时间,
和你原来采用的模型对比,速度有什么差距,连接数有什么差距
因为你从客户端连接上看,确实成功了,但是关键的一步就在那里,你的CONNECT返回成功,实际上你的连接还没有完全完成,只是躺在系统的等待队列里面,这就是区别
已经告诉你了,
那个是等待队列的速度和连接数,而不是什么模型的速度和连接数,从根本上就是没有意义的。******************************************另外我说的连接成功不是在客户端统计的,使服务器的accept返回后才增加的计数器
正因为这样,我才知道这里面的关键问题所在
一个32位进程能做出51000个TCP连接,我是非常非常非常佩服,
我老实的承认,在我所有的32位服务设计下,单进程我无论如何都做不到
所以很佩服很佩服
我给你个最简单的对比,
使用阻塞SOCKET
开启一个线程
执行
while(1)
{
s_new=accept(s_server,...);
if(s_new==INVALID_SOCKET)
{
//error
}
else
{
::InterlocketIncrement(&mi_total);
//add something you want
}}和你的模型对下速度吧,谁快?差距多少?
用最基本阻塞SOCKET也能做到[email protected]我的意思是,32位下,单进程实现这么多TCP连接,除非测试连接用,否则是不现实的
我的意思是,32位下,单进程实现这么多TCP连接,除非测试连接用,否则是不现实的绝大部分的情况下的确不现实,但是说句实话,我正在公司新产品的构架中引进了这种机制,具体出于什么原因在这里就不方便说了 呵呵,代码我马上给你发过去
你发送完1024字节后,是断开连接,还是继续挂着?你的SERVER SOCKET有没有在LISTEN前修改过SOCKET参数?默认下 8+8KB * 32530=520480KB,也就是你的物理内存几乎全部被SOCKET吃光了,我觉得......
CPU: 至强2.6G X 4
Physical memory:4G
Other:......(不说了)
测试过服务器接受连接:>6W个,客户端随机选择500个socket发送一次(2K)再随机选择500个发送,而服务器接收到后返回数据,运行非常良好!
[email protected]
转移个话题,我觉得难度不再是使用I/O,还是Overlapped,还是WSAEventSelect来实现,而在于对报文的处理逻辑。
至于模型就那么几种,框架例子也就那么1/200行代码,问题是以什么逻辑来处理收发和报文的应用层处理,以及输入输出的效率,才真正体现架构的合理和技巧性。
比如:各位处理每个连接的收发是不是放两个队列来循环投递的,也就是说每个连接最多占用两个收发的buffer。
又比如:收到一个完整的报文是放在独立的线程还是放在IO处理线程里面处理为好呢?
。。
希望各位高手也能向上面那样讨论下,让俺们再张点知识!!
谢谢!研究一下
线程池如何设计,不用WSAWait...函数他是有限制的,如何做到连接达到几万个。那得启动多少个线程???
学习,谢了!
[email protected] 其它要代码的朋友我现在在家代码得明天发了,不好意思
学习,谢了!
转移个话题,我觉得难度不再是使用I/O,还是Overlapped,还是WSAEventSelect来实现,而在于对报文的处理逻辑。
至于模型就那么几种,框架例子也就那么1/200行代码,问题是以什么逻辑来处理收发和报文的应用层处理,以及输入输出的效率,才真正体现架构的合理和技巧性。
比如:各位处理每个连接的收发是不是放两个队列来循环投递的,也就是说每个连接最多占用两个收发的buffer。
又比如:收到一个完整的报文是放在独立的线程还是放在IO处理线程里面处理为好呢?
。。
希望各位高手也能向上面那样讨论下,让俺们再张点知识!!----------------------------------------------------------------------------我是这样写SERVICE的 结构是多线程 WINNT SERVICE 进程
两个监听SOCKET,阻塞,分别由两个线程负责,称为ACCEPT线程
数目可根据需要改变的主引擎线程,一个负责协议A,一个负责协议B,可以根据需要分别开启1-N个线程(根据CPU数,如果要限制资源占用,全部设置为1,默认为1)
数目可变的数据处理线程,专门负责处理检索和分解整理等需要耗费大量CPU时间的任务,根据CPU数来设置
数目可变的数据库处理线程,负责处理用户数据,例如登录,参数修改等
系统守护线程,用来检查系统目前的运行状态并记录,数字为1两个线程执行阻塞的SOCKET ACCEPT,专门负责新连接的接收,并在接收的时候检测进程内存使用是否已经达到危险程度,是就丢掉,否则再检查系统限制数,所有一切都正常,放入全局结构(预先一次性分配,防止碎片,大约需要0.2KB/连接),由指令处理线程来执行处理两个指令处理线程,分别处理针对两个协议的连接的指令,这才是真正的核心引擎,之前曾使用过线程池模型,速度快,但是内存消耗实在太大,也尝试过IOCP,但是遇到攻击代码,出现攻击性数据消耗了系统大部分资源,我无法用自己的代码进行控制,由于安全问题同样被我放弃,最后使用的是非阻塞SOCKET API,这样可以控制每秒执行的指令数,并可以控制网络传输速度,做到公平性。为什么不使用WSA函数,因为这系列函数,无法利用WIN2K的IP层防护,老外的资料里有的,针对IP FLOOD攻击有问题(WSAACCEPT),我没有查到MS是否解决了这个问题,所以干脆不用,直接使用SOCKET函数写的,没有使用一次SELECT 64个,和64次READ或者PEEK代码的执行速度比快是快了点,但是在我的引擎中很难处理,所以没有使用SELECT 64个,而是首先检查ACTIVE状态,活跃的才调用READ或者SELECT,如果处于任务中,则调用任务处理函数。 所以随便CLIENT怎么攻击,服务器的处理速度是恒定的,大流量攻击数据都被阻塞在TCP层上,也不管你发送的包是否符合要求,或者将N个协议指令一次性打包发送过来,或者发送半个包,都能安全并准确识别。 这里涉及到的主要问题是对不完整指令的处理上,也就是假如一个指令完整应该是 1234567890\n,现在CLIENT只发送了123456,没下文了,如何处理? 其实很简单,我是使用状态指示和SOCKET时间来控制的,如果我的引擎在指定时间内,例如120秒,无法收到完整的指令,那么对不起,我BAN你,该连接结束,这没什么好对不起或者死等待的,最大的可能是用户物理断路了或者服务器遭遇了碎片式的慢攻击,坚决踢掉。还有一个就是应该是一个指令一个指令来,但是用户如何一下发了N个指令怎么办?不合法,这就看你怎么认识,我认为是合理的,所以我在服务器端,不管它发送N个指令,我只是将它接收到有限缓冲,然后按每秒处理规定指令数进行处理,尽管在协议上来说是不正确的,但是我是这么处理的。还有一个概念是安全,100%的安全是做不到的,但是至少保证50%的安全,我看到楼上有人几万个连接,同时500个CLIENT发送几K数据做测试,这是不合适的,那是你基于人性本善来看待你的用户,不去说通过代理服务器进行并发攻击,要是万一几万个合法用户同时发送几KB数据,你怎么办?测试这东西不能做假设的,需要用极限数据来测试,你有几万个连接,你就必须确保能及时安全处理几万个数据的并发; 有个笑话,做同一个程序,我花了三天,IBM用了一个月,运行开始,三天后,我的程序崩溃,IBM的运行了一年。
楼上所谓的我要直接控制和监督SOCKET传输,这种,难道WSASend的不能控制吗?你也可以用WSASend来实现Send的效果啊?
当然,这是我个人的理解,呵呵,希望能在讨论中取得进步。
为什么不被重视,是因为主流的例如MAIL,FTP,WWW的开发都是基于BSD SOCKET开发的,并没有使用WSA系列函数,一般不存在该问题,而使用WSA编写的服务器软件,也许加了第三方防火墙,或者在路由层使用了什么技术来防止IP FLOOD,很少有直接暴露的,即使有,估计也没几个人会用FLOOD 来攻击
你说的这个IP安全性问题,应该从两个方面来理解,一种本身可以利用操作系统级别的IP防护,还有一种就是通过第三方软件来防护,但是很遗憾,至少我知道,在WIN2K下,WSAACCEPT函数存在这个问题,虽然很隐蔽,但是确实存在,而BSD的实现是可以直接受WIN2K IP层防护的,至于为什么,我也没搞明白,到今天都不明白,但是只要有安全问题,我就不会采用WSA。你没有理解我的非阻塞SOCKET的意思,不是ASY,ASY立即返回,而非阻塞将发送到全部被发送或者缓冲满,ASY方式将立即返回然后采用事件通知,这个方式对我来说时间无法预测,我不会采用的。 因为这里有一个防止碎片攻击和碎片接收以及指令传输时间控制的问题,我必须监督从反馈信息的开始发送时间到目前时间的时间差,不能等到有消息了才去检查至于为什么采用阻塞ACCEPT,因为这个最简单了,没必要使用系统消息的方式来进行,这个相对来说效率也是最高开销也最小,因为引擎的需要,这部分必须被独立出来执行,所以就用了两个线程来执行
我认为这不可能,试问 FLOOD攻击最早是什么时候出现的? 那时候还没有WSA呢!-----------------------------------------------------------------------------
你没有理解我的非阻塞SOCKET的意思,不是ASY,ASY立即返回,而非阻塞将发送到全部被发送或者缓冲满,ASY方式将立即返回然后采用事件通知,这个方式对我来说时间无法预测,我不会采用的。 因为这里有一个防止碎片攻击和碎片接收以及指令传输时间控制的问题,我必须监督从反馈信息的开始发送时间到目前时间的时间差,不能等到有消息了才去检查怎么可能不知道呢,任何一种网络IO都可以在应用层实现啊? 如果按你的理解启不使不用BSD 的都无法预测时间了?这怎么可能,我想不明白
呵呵 大部分都被阻塞在 client 端了,你怎么知道的?我想说的是任何一个服务器遇到这种问题都是无能为力的,包括你的模型,因为这些数据在ip层是无法发现并过滤得都得交到你的应用层,经过你的检测你才能发现,但是如果这样的数据大量涌入你的ip 层,然后ip层交给你的应用层,你说你处理的是不是都是错误的数据,那你还那里有时间处理正常的用户请求了
我认为这不可能,试问 FLOOD攻击最早是什么时候出现的? 那时候还没有WSA呢!汗,解释不清楚,FLOOD是IP层,我们引擎够不到的,只能有操作系统去负责对吧?
你就这么理解吧,BSD 和WSASOCKET的实现是通过操作系统的TCP层,然后操作系统负责的IP层,然后数据链路,然后物理层来进行,[以下是我的假设推论,事实是否如此我不知道]
现在WSA的实现在IP层 FLOOD时出现了问题,也就是当操作系统遇到IP FLOOD攻击的时候,操作系统能够识别BSD SOCKET的ACCEPT实现提供防护[例如自动拒绝或者关闭什么的],但是不知道为什么,它不会为WSAACCEPT提供防护也就是说MS的 WSAACCEPT的实现存在问题,它遇到IP层的FLOOD攻击的时候,无法象ACCEPT实现那样自动被NT操作系统保护,原因别问我,我也不知道关于时间的监督和控制,从安全角度来理解可能更加容易,假如SOCKET SEND-BUFF为0,现在你必须在60秒内将响应消息发送给CLIENT,而CLIENT是个恶意的CLIENT,它每秒只接收1个字符,RECV-BUFF也是0,1600个字符,1600秒,应该在60秒时就识别出是恶意的CLIENT,如果安全级别提高,那么因该在30秒左右提前识别出是个恶意的CLIENT
呵呵 大部分都被阻塞在 client 端了,你怎么知道的?我想说的是任何一个服务器遇到这种问题都是无能为力的,包括你的模型,因为这些数据在ip层是无法发现并过滤得都得交到你的应用层,经过你的检测你才能发现,但是如果这样的数据大量涌入你的ip 层,然后ip层交给你的应用层,你说你处理的是不是都是错误的数据,那你还那里有时间处理正常的用户请求了
//------------------------我理解错了,你说的是IP层的SYN FLOOD或在错误IP包,不是我们协议层的不完整指令吧
我把你的话理解为协议层的不完整指令恶意攻击了,IP层我们够不到,听天由命了如果是协议层(TCP),我们的引擎将确保将大部分连续指令阻塞在客户端,因为我控制的SOCKET缓冲只有4KB,超过4KB的部分,不等到我们的引擎处理掉这缓冲里的数据并读取新数据,TCP窗口为0,CLIENT根本无法进行这种攻击的,只能被阻塞。这和IP层错不错没关系的。我只能确保TCP层,IP层神仙也保证不了,我们又不是写防火墙软件。
呵呵,说说我的理解,客户端发送1个字节的报文给服务器,服务器肯定会通知Recv事件的,我觉得这个只有到应用层才可以处理,只有用户处理过了才知道是不是合法数据,我不认为有什么机制可以在内核层就能判断这个为非法数据或者因为缓冲区不满就不通知。。
呵呵,说说我的理解,客户端发送1个字节的报文给服务器,服务器肯定会通知Recv事件的,我觉得这个只有到应用层才可以处理,只有用户处理过了才知道是不是合法数据,我不认为有什么机制可以在内核层就能判断这个为非法数据或者因为缓冲区不满就不通知。。不是IP层的碎片,是TCP层慢攻击导致的小包,现在很流行的,XX服务器被攻击,就是使用的大量代理服务器发送这种包导致的合法攻击,可以通过引擎的时间判断来提前识别这种攻击的,操作系统识别不了这种攻击的。
你通知1800次,处理1800次
我的引擎,执行300次检测,处理300次
你通知1800次,处理1800次
我的引擎,执行300次检测,处理300次****************************************************
你是怎么做到的,在解释解释
连通知都没有,我找上门去才说SORRY,忘记通知了,所以现在非常重视安全
网络模型对我的实现来说是次要的,没必要搞的很复杂,因为我的是面向公网的开放协议,数据流量很小,只有协议层的数据,最简单最安全就行,
但是我必须面对各种攻击,所以很大部分的代码和逻辑函数都用在了安全方面
客户端才考虑效率优先。
也发现很多问题:
1.假如客户端使用非阻塞方式连接服务器段,使用重叠i/o时:WSARecv函数执行失败(可能socket没有真正连接上,只有执行下面的select才开始连接)
2.重叠I/O模式不能使用WSAWaitForMul...函数来等待事件的触发,如何能使连接的数量很大,靠增加线程数量?这不是玩笑话!!!
3.控制协议中:没有接全一条指令如何处理?