大讨论:关于VB Winsock。解决思路

大讨论:关于VB Winsock。
近来用到了winsock,有些地方钻研不够深入,所以想与各位讨论一下。
在VB中,服务器的winsock瞬间的连接量大概在三四十左右。也就是说,同一秒内,有三四十个客户端连接到服务器,因为使用的是tcp,所以就使用了winsock的控件数组,有多少个连接就建立多少个winsock。请问,如果这个瞬间的连接量再大很多的话,服务器能不能承受?比如说1000或者更多。
当然,这个瞬间的连接量只是服务器程序刚刚启动时才有的,因为客户端是有限的,所以就现在的情况来看,最大的连接数是100.
因为以后要增加客户端,所以在服务器程序打开的时候,客户端就会一起对服务器进行连接,这个连接时很快的,在服务器开始的一两秒内,就会有1000甚至更多的Tcp进行连接,服务能不能承受?

------解决方案--------------------
从控件的角度来看,只要用于分配应答ID的那个控件在成功分配一个请求到另一WINSOCK控件之间的时间内,没有新的请求到来即没有问题

但是这个不太好测试,要构建的环境不容易得到.

楼主如果是为了保证连接的可靠性,那么可以从流程上进行优化,即客户端在连接时增加超时与重试机制,这样只要网络没问题+服务器端程序没问题,就一定可以处理完所有的请求.

比如一秒内并发1W个请求,但服务器端程序最多只能在一秒内应答1000个,那么假设客户端重试为3秒一次,则最坏的情况是27秒左右处理完所有请求.

由于服务器端处理能力有限,速度肯定慢下来了,但这样至少能保证全部请求的处理.
------解决方案--------------------
必须用多线程。

假定服务器处理一个请求需要10毫秒的话,不用多线程处理1000个请求需要10秒钟的时间,按照每秒钟有1000个请求,10秒钟就有1W个请求,那么就有9000个请求得不到及时处理,用不了几分钟你的系统就完蛋了。

用多线程的话1000个请求被分到了1000个线程里面去处理,1W个请求被分到了1W个线程里面,各自处理各自的不存在谁先谁后的问题,每个请求都能得到及时的处理。

所以必须要用多线程来做,至于同时可以有多少客户端连接,这就取决于你的服务器性能了。
------解决方案--------------------
探讨
必须用多线程。

假定服务器处理一个请求需要10毫秒的话,不用多线程处理1000个请求需要10秒钟的时间,按照每秒钟有1000个请求,10秒钟就有1W个请求,那么就有9000个请求得不到及时处理,用不了几分钟你的系统就完蛋了。

用多线程的话1000个请求被分到了1000个线程里面去处理,1W个请求被分到了1W个线程里面,各自处理各自的不存在谁先谁后的问题,每个请求都能得到及时的处理。

所以必须要用多线程来做,至于同时可以…

------解决方案--------------------
1、不要使用多线程,否则你会死得很惨,因为你是VB来开发,而不是VC;
2、我曾经参加过一个项目,是关于出租车GPS连接的。刚开始时有1000多个车台要登录到服务器上,并且每个车台在一分钟之内要上发一条消息到服务器上(每条消息大约150个字符),没有出现过数据丢失的现象。后来扩展(增加车台的数量),一直到现在都没有出现问题。但是需要强调的是,在连接丢失后,要自动地将废弃的socket对象释放,并保证能够被重新分配给新的连接(原因是:A.没必要维护不用的socket对象;B.控件数组的index为integer对象,如果不循环使用,小心会溢出)。
------解决方案--------------------
探讨
从控件的角度来看,只要用于分配应答ID的那个控件在成功分配一个请求到另一WINSOCK控件之间的时间内,没有新的请求到来即没有问题

------解决方案--------------------
探讨
LZ可以去看IOCP原理,不过用vb做,即使可以用完成端口,估计也没什么效率...

用SocketMaster可能要好点

------解决方案--------------------
探讨
从控件的角度来看,只要用于分配应答ID的那个控件在成功分配一个请求到另一WINSOCK控件之间的时间内,没有新的请求到来即没有问题

但是这个不太好测试,要构建的环境不容易得到.

楼主如果是为了保证连接的可靠性,那么可以从流程上进行优化,即客户端在连接时增加超时与重试机制,这样只要网络没问题+服务器端程序没问题,就一定可以处理完所有的请求.

比如一秒内并发1W个请求,但服务器端程序最多只能在一秒内应答1000个,那么假设客户端重试为3秒一次,则最坏的情况是27秒左右处理完所有请求.

由于服务器端处理能力有限,速度肯定慢下来了,但这样至少能保证全部请求的处理.

------解决方案--------------------
Winsock控件的index属性本来就是个安全的多线程,在很多时候,也有很多人用纯API来自构SOCK应用层,但一般都过不了index这关,别小看这个多线程,如果自己用VB6 API自已写,这个就是最大的问题.

如果在同一时间点,连接数大于Index这个数,那么也不是没办法,当在load sock时发现state都为连接状态则winsock1肯定会报错,在ERROR事件捕捉这个情况,用winsock2反连客户端,告诉客户端新的端口号,客户端根据新的端口号重连服务器端,当然,一般都不会让客户端重连服务器,一般在客户端都会提示用户:连接数已满,您正处于排队中,在您前面还有X个用户.

但上面的情况,一般来说会碰到的情况机率不高,除非你做大型网络平台(比如网络游戏),那么可能在同一时间点,连接数大于32766,
------解决方案--------------------
楼上的,vb.net,和vb差不多
用vb.net写个多线程的Winsock监听
我的程序是这么实施的,服务端没有用vb写,
默认最大连接数是3000个(同一时间),也就是说最大线程是3000个.(连接数个人设置的)
每个线程自动处理数据.如果连接数超过3000,服务端可以设置,[超过最大连接数是否重启]服务端(exe)
开100个线程,服务端不超过40M内存,CPU影响不大
------解决方案--------------------
探讨
1、不要使用多线程,否则你会死得很惨,因为你是VB来开发,而不是VC;
2、我曾经参加过一个项目,是关于出租车GPS连接的。刚开始时有1000多个车台要登录到服务器上,并且每个车台在一分钟之内要上发一条消息到服务器上(每条消息大约150个字符),没有出现过数据丢失的现象。后来扩展(增加车台的数量),一直到现在都没有出现问题。但是需要强调的是,在连接丢失后,要自动地将废弃的socket对象释放,并保证能够被重新分配给新的连接(原因是:A.没必要维护不用的socket对象;B.控件数组的index为integer对象,如果不循环使用,小心会溢出)。