关于一个server对应大量client通讯的效率的问题(100分)

  • 主题发起人 一个过客
  • 开始时间
你一个线程等待64个对象WSAEvent,其中一个是对象是又新的CLIENT加入的时候的信号对象
一个对象WSAEvent对应一个套接字,你做一个线呈数组,一般100个线程就可以提供6000
个连接,基本上就够了
 
在瘟环境下,如果想服务大规模的用户,智能够用用完成端口,服务中使用重叠I/O。
同意 张无忌, 方法正确!
也不是太难!就是测试麻烦。没有那么大的实际环境。
 
客户端可以在启动的时候(或者适当的时候)主动请求消息嘛
 
讨论了半天,也没有给出一个完成端口的例子模型!
 
我也比较愚钝
没明白'重叠I/O'在这里怎么工作的
没怎么能节省时间
 

轮巡的时间应该很短啊

 
1。。 只能使用完成端口+线程(线程多少根据你线程里要处理的时间和连接数决定),解决连接数多的问题
2。。 用啥希表、二分法等,解决轮巡过长的问题
 
1000次循环的效率也要担心? 楼主用的什么古董机器做server? 不会是计算器吧?
 
其实可以不必运用多线程,多线程的资源损耗!和切换!其实淤你轮巡并没有好到哪里去!
 
关注
我想在非阻塞方式下,循环1000次应该不会占用多少时间的吧,又何必用什么多线程之类的。
我是刚刚接触这个的,请大侠们多多指导。
 
我的方法是.在Client端做文章.你的消息功能是一个接口.
你可以自定义Client端在什么时候去Check Server上有没有新消息.
这样工作尽可能得分散.
 
同步模式下耗时间,用indy一般都是同步的,换成异步模式看看。


 
关注啊。
这样的Server可以带多少个Client?
 
我用D6的tserversocket / tclientsocket 控件,做一个TCP/IP的软件。

我的客户端是一个GPRS 终端,所以不用管它。可是,终端它可能有不可知的中断,比如突然断电等情况,所以这里就有一个问题:当终端不可知的中断的情况下,主站是肯定不知道的,而且,socket 连接的数组也不会减少的,也就是中断的SOCKET 套接字不能及时的删除,那么主站它会定时下达指令时,也会向这个已中断的SOCKET发指令,所以这时发关的指令是无法返回的。请问我要如何维护SOCKET 的CONNECTION[K],就是要删除数组中的某个数;

serversocket.socket.connection[k].close;
以上这句是用来关闭一个连接,但不是用来删除数组中的一个数;
 
兄弟用TNMUDP可以广播哟
 
晕!!!
大伙儿怎么都想着让一台服务器干这个活啊!难道让厂长直接对工人一个一个说???
厂长对分厂厂长广播,分厂厂长对车间主任广播,车间主任对工人广播,每次的广播任务都不重,但得到消息的人却呈几何级数增长,极短的时间,地球人都知道了!!
 
to solonet:
tcp/ip本身就是这样的,如果需要实时的检测socket是否有问题,只能是不断地收发测试协
议消息,当在间隔时间内发送或者接收失败时,就可以认为socket有问题了,可以强制关闭。
 
首先,股票软件的数据是每分钟一次,而且是有需求的client发请求,服务器响应而已;
其次,象你说的需要广播的情况是有,比如聊天室,但是你可以看看,一个聊天室服务器服务2000用户,并不代表这2000用户都在一个房间里,而只有在一个房间的时候才需要广播通知,所以最好的办法是设计上分开逻辑组,那么广播的时候就只需要广播几个-200个左右的client了,现在一般的房间都只允许进200个人左右就是这个道理.
再次,如果说一定要做千人级别的广播,那么时延是避免不了的,而且势必要常常砍掉那些网络不好的client,以加快速度.下面是对这种情况的分析:

如果用阻塞,在遍历发送时最大的问题就是,这1000个client其中某几个client网络不好甚至断线了,那么单线程遍历发送时,剩下的client就要等,而如果通过设置一个比较短的超时的办法也不理想,因为可能会导致有些网络不好不坏的client收不到,所以用异步的完成端口确实在处理方面要简单一些,而且不用你关心线程方面的细节,效率相当高,实际上等于是系统内部帮你处理了线程操作.不过如果需要能够移植到linux平台,建议使用线程池,估计效果还不错,比如你池里有50个工作线程,50个线程同时都遇上网络不好的client的机会比较小,再加上你设置了一个中等时间的发送超时,我想这样的设计应该是比较好了.不知道比起完成端口的效率会有什么区别,没环境测试啊,不过我从理论上的感觉是应该差不多的,因为我认为完成端口就是一个线程池,而且它的同步以及通知还用到了事件对象,而你用线程池的话,可以使用效率更高的临界段.
 
我用D6的tserversocket / tclientsocket 控件,servertype采用:stNonBlocking ,做一个TCP/IP的通信软件。

我的客户端是n个GPRS 终端,所以不用管它。可是,终端它可能有不可知的中断,比如突然断电等情况,所以这里就有一个问题:当终端不可知的中断的情况下,主站是肯定不知道的,而且,socket 连接的数组也不会减少的,也就是中断的SOCKET 套接字不能及时的删除,那么主站它会定时下达指令时,也会向这个已中断的SOCKET发指令,所以这时发送的指令是无法返回的。请问我要如何维护SOCKET 的CONNECTION[K],就是要删除数组中的某个数;

serversocket.socket.connection[k].close;
以上这句是用来关闭一个连接,但不是用来删除数组中的一个数;


************************

//统计在线的终端数:
statusbar1.Panels.Items[5].Text:= inttostr(serversocket1.socket.activeconnections);


用以上这句可以统计在线有套接字数,也就是有多少可用的SOCKET,但问题是假设目前我只有3个测试点,可能是中断后再登录上来,所以统计出来有5或者更多个。请问我要怎么正确维护socket的connection 的数组啊?
也就是我有几个终端,就应该有几个SOCKET。

***********************

我还用ListView1,来记录当前登录的终端,ListView1记录有如下几个项目:
序号、GPRS ID 号、终端IP 地址、端口号



var
newitem:tlistitem;
-----------------------------

//登录的子站
newitem:=listview1.Items.Insert(listview1.Items.Count); //插入的位置;
newitem.Caption:=inttostr(listview1.Items.Count-1);
newitem.SubItems.Add(gprsid);
newitem.SubItems.Add(socket.RemoteAddress);
newitem.SubItems.Add(inttostr(socket.RemotePort));



请问我要如何才能保证有效的SOCKET与LISTVIEW1中记录的一致?这样才能正确通信。



谢谢!


对了,我的网名叫:solonet

qq:28972303

email:solonet@163.net
 
还有:
1,CONNECTION[K] 不是静态数组,它大小是随SOCKET在变化的,它是一个LIST.
不能通过序号,而是要通过IP和PORT来定位指定客户SOCKET,对吗?

2,serversocket.socket.connection[k].close;会自动释放对象,并将
对象从LIST中删掉,而且connection[k]也会减少的,对不对?

那为什么我用:
serversocket.socket.activeconnections时,返回的数值是大于我的真实个数呢?


 

Similar threads

S
回复
0
查看
747
SUNSTONE的Delphi笔记
S
S
回复
0
查看
696
SUNSTONE的Delphi笔记
S
D
回复
0
查看
792
DelphiTeacher的专栏
D
D
回复
0
查看
747
DelphiTeacher的专栏
D
顶部