300分在线等!在做(TCP/IP)服务器程序中所遇到的難題(希望有经验的人士一些解决方案)(200分)

  • 主题发起人 主题发起人 wx_ham
  • 开始时间 开始时间
W

wx_ham

Unregistered / Unconfirmed
GUEST, unregistred user!
项目基本的情况是这样的:
在服务器端是的Delphi自带的TServerSocket,客户端是用的Delphi 6自带的TClientSocket
用的的TCP连接,非UDP。非阻塞模式。
当服务器需要向客户端广播的时候(因为系统中需要数据准确性,就是说客户端一定要收到服务器的数据),如果有600个左右的用户,则每秒钟只能发送150个左右的用户,也就是说600个用户需要发送4秒钟左右,这么长的时间是无法容忍的。不知道大家在做的时候有没有一些好的经验可以借鉴?

注:不希望改成UDP来传输,而且因为时间紧,所以最好也不说使用别的控件,因为改控件对系统带来的时间可能来不及。
 
好象主要问题是因为TCP协议的关系,网络比较慢,必须等TCP握手成功以后才可以发送信息,即使你设置了非阻塞模式

改为UDP方式发送,手动控制握手状态是最好的,如果一定不希望这样做,你可以试试用多线程分组发送这600个用户,比如100个一组等。。。
 
to:
hs-kill

用UDP方式发送数据,在多网段Internet上面好像不太灵光。

用多线程发送会对效率有所提高吗?我都是通过一个TServerSocket来进行发送的。我现在还没有测出是服务器IP栈堵死了,造成的延时,还是因为别的原因。

如果是服务器IP栈忙的话,用多线程那岂不是一样的。
 
你只能使用多线程 别的就没有办法的,你假设600个人 你使用TServerSocket 的话 就的给和TServerSocket 连接的任何一个分别发送一次, 简单的讲 从一数到600还的需要个时间延迟呢 ,你要多线程的话 ,这个就可能时间短点,
 
这个延时是比较正常的,不知道你发的数据有多大,如果没用到广播或组播,那肯定要轮询每个用户,600个用户,4秒的延时,看来你还只是发送几百个字节左右的文字信息。
即使你改成线程方式,也不会有太大的提高。
比较好的办法是提高硬件性能和网络出口带宽
 
to truest9
的确,发送数据也就是几百个字节左右,
我觉得硬件应该是够了,一般的硬件占用只有40%左右,网络出口占用也是比较少的。

硬件配置:至强3G*2的CPU,2G的内存,
网络:电信10M独享,网通100M共享

是不是按你的意思就是:加入组播和广播???
 
我仍然坚持是因为TCP协议造成的发送缓慢(你可以尝试单独写个程序对一个网站连续连接600次,看看速度是多少)

举个不太恰当的比喻:
使用UDP方式就相当于你写个for i:=1 to 600 do的空循环
而使用TCP方式,就相当于这个循环体内要等待客户机的响应消息才进入下一条循环

你判断是否收到消息可以在客户端设定一个接受信息并返回信息的部分,类似TCP的握手,不过不需要阻塞等待返回结果
 
hs-kill
楼主已经是使用了非阻塞模式,在这个发送循环体内并不需要待调用结果。
而且UDP也存在阻塞与非阻塞模式,你这个比喻的确不是很恰当呢
 
你可以试着改为阻塞模式,然后为每一个用户创建一个发送线程并处于就绪挂起状态。当有发送任务要执行时,就恢复线程执行,进行数据发送,发送完成后返回挂起状态。
这种结构在调用send循环上花的时间更少些
另外,广播和组播一般只能用在局域网,互联网上的路由器几乎没有开放这些功能的。
 
NONO 我所谓的等待是指TCP的3次握手。。。无论是否阻塞都需要等待握手成功才可以发送数据

UDP比TCP快就快在不需要握手
 
楼主希望多长时间完成呢? 1秒还是更短?
 
硬件配置:至强3G*2的CPU,2G的内存,
网络:电信10M独享,网通100M共享
------------------------------------------------
我想问题出在这边,服务器到各客户端的数据丢包情况怎么样?
你的服务器是双线单IP的吗?把这些情况说详细一点,这很重要
 
也希望大家对电信和网通互联互网的模式提出较好的解决方案
 
使用阻塞模式,用不同的端口同时处理,开多几个线程,应该能增加速度。

编程比较麻烦,就是要处理好 端口值 冲突问题,要不还是阻塞啊。

lz的要求没写清楚啊:
1、内网还是internet?internet怎么广播?...
2、内网是dhcp分配还是指定固定ip?
3、数据形式?二进制流还是文本?
4、目标的机器没开,算不算丢包?
5、数据包丢失是重发还是写入log?
6、需要回传数据吗?
 
问lz二进制还是文本是因为这样考虑的:
如果是文本,干脆在服务器上建立一个数据库去实现,应该很快的,而且不用考虑那么多冲突问题,还有就是跨网段也能做到,不过效率不好,因为客户端要定时查询。

呵呵 这是题外话,实际上也是中断和查询的关系啦,孰优孰劣,自己看情况决定啦,开拓一条思路而已。
 
to:jenhon
1/程序是在Internet运行的,而不是在局域网内运行,用广播可能不太现实。
2/服务器是放在交换机后,用的端口映射,交换机走双线。
3/二进制流
4/不算
5/数据丢失选择重发
6/数据接受不完全时回传

建一个数据库供用户查询似乎不太现实。
 
to dira
服务器是放在交换机后,用的端口映射,交换机走双线。电信10M独享,网通100M共享
 
双线路我现在也碰到这个问题,双线与单纯的电信线路来说丢包和延时都很厉害,不知道你那里怎么样?有没有测试过?
 
to all
谢谢大家支招。
昨天晚上回去后,改成了多线程发送的模式,但是效果不是很理想。
时间上大约节约了1S左右吧,
多线程发送过程中还造成了发送给用户的信息相当的混乱:有些应该优先发送的数据被延后。
 
至强3G*2的CPU
------------
那用多线程.一定会快点的.因为你是双CPU
 
后退
顶部