sockets,tcp连接,并且是长连接,当终端有2000个以上时,如何实现稳定地接收终端数据(同一时间点可能有数个终端同时上传数据) ( 积分: 300 )

  • 主题发起人 主题发起人 耗子_super
  • 开始时间 开始时间

耗子_super

Unregistered / Unconfirmed
GUEST, unregistred user!
本人在做一个监控系统,是通过gprs通讯方式传输数据。
编程上一定要采用sockets,tcp连接,并且是长连接(这三个条件是肯定的,无法更改),当终端有2000个以上时,如何实现稳定地接收终端数据(同一时间点可能有数个终端同时上传数据)。
在终端不是很多的时候,一般我们都是采用为每一个连接建立一个线程,那么可以很容易的实现稳定的接收所有终端的数据。可是当终端有数千个的时候,如果针对每个连接都建立一个线程,那么计算机肯定是吃不消的。
如果就用一个监听线程,然后写循环对所有的连接进行检测有无上传的数据,那么问题又出现了,当某个时间点有数百个终端同时上传数据,很有可能会漏掉一些终端上传的数据。
欢迎大家参与讨论,谢谢!
 
本人在做一个监控系统,是通过gprs通讯方式传输数据。
编程上一定要采用sockets,tcp连接,并且是长连接(这三个条件是肯定的,无法更改),当终端有2000个以上时,如何实现稳定地接收终端数据(同一时间点可能有数个终端同时上传数据)。
在终端不是很多的时候,一般我们都是采用为每一个连接建立一个线程,那么可以很容易的实现稳定的接收所有终端的数据。可是当终端有数千个的时候,如果针对每个连接都建立一个线程,那么计算机肯定是吃不消的。
如果就用一个监听线程,然后写循环对所有的连接进行检测有无上传的数据,那么问题又出现了,当某个时间点有数百个终端同时上传数据,很有可能会漏掉一些终端上传的数据。
欢迎大家参与讨论,谢谢!
 
我想你可以试试以下的方法:
1.监控程序由被动接收改为主动接受
这需要终端具有一定的存储功能(我不清楚你的终端是否有存储功能),由监控程序向终端发布数据上传得命令,终端进行数据上传。

2.数据接收进行分流(负载平衡)
即多台计算机同时进行数据的接收,每台计算机有一定的连接数量,超过连接数,就将连接让其他机器接收。
 
关注此题,学习
和我做的一样
socket控件本身封装了多线程吧
(当然你如果自己写又是另一回事)
不用自己去控制吧
 
to z-jackey:
1: 终端是买的人家的通讯模块,没有缓存功能。而且既然是监控程序,就应该是终端随时有数据,随时就得上传。不能监控程序先下传个命令,终端再上传。

2: 这种方案好像也不大显示,就算客户肯答应,编程上面的难度也很大,而且服务端就只有一个公网的ip
 
to 耗子_super:
方法二:只要一个ip,在计算机上可以开多个端口。你可以参考Indy控件的Tcp的Server和Client的写法
 
Indy的Tcp的Server有一个端口是公开的,那就是监听端口。当建立连接时,他会开放一个随机端口进行连接通讯。

不过对于负载平衡上确实是具有开发的难度
 
线程不能有几千个,但是数据缓冲区可以有几千个,
为每一个连接设置一个数据缓冲区,取得数据直接转到对应的数据缓冲中去,
以另外的线程处理数据
 
to 魏启明:
“数据缓冲区可以有几千个,为每一个连接设置一个数据缓冲区,取得数据直接转到对应的数据缓冲中去,以另外的线程处理数据”。
能不能详细的说明一下,或者给些资料,demo我自己研究一下,谢谢!
 
还好我只有一、二百个终端

我觉得方案也只有z_jackey说的2比较可行,几台计算机分别接收
 
有解决方案,我另加100分哈,谢谢
 
to uiit:
你的1,200台终端,就是开1,200个线程吗?机器能吃得消吗
 
我用socket控件
线程封装好的,一般情况挂起
没问题

我没试过200以上
 
to uiit:
能不能把你那段代码发给我看看呢?另开帖送200分
 
如果带宽没有问题的话就没有问题,还有一次数据量有多大?
 
对一台服务器,同时开几千个线程,肯定是吃不消的
我觉得可以考虑下面的几个方法:
(1)用一台专门用的中间服务器来接收客户端的数据,这样几百个连接不会有什么问题的。
(2)连接超过一定数量时,另开一个端口,(可同时开多个端口)对不同点的客户端采用不用的端口。
(3)对某些端口(就是某些点)的数据缓冲到中间件上,由别外一个应用(中间件上的应用)负责处理这部分数据到服务器端。
(4)客户端太多时,绝对不能对每每一个客户端开一个线程。
 
控制连接数量
 
to 耗子_super:
本身代码没什么,就是应用socket控件
不知道你有没有ScktComp_6控件
这是D6带的一个socket控件
还有终端是我们自己做的,所以带有缓存功能,但只要连接成功
数据是可以接收到的
由于还在应用阶段,不知道到底会不会有这样的问题
当然如果终端处理不好,都会漏数据的

你有的话我会发那段代码给你的
 
最近也在做一个监控的程序,客户段linux(100台),sever段准备用TseverSocket做,

我的问题是:当,100台都连接sever端的时候,这个时候我想从server端,传一个文件/一条指令给谋一台(例如:1号),我如何操作? 如何得到那个socket_fd?
 
在什么操作系统下
通用的写法可以是
起动 一些线程 每个线程 带 64 个socket (最多带64)
在Socket 上用 select (300 多个线程即可) 关于select 的用法 可以随便
在网上找到

做监控系统 的话 可能要把媒体信道和控制信道分开 也就是
至少为每个终端 开两个 socket 一个用于发送 控制信令 一个用于发送媒体
(发送媒体 根据不同的协议或自己定的协议可适当加端口 )

如果在windows 下 select 是效率最低的 可以采用 WSAEventSelect 或 完成端口等来

提高效率

一个服务器要带 2000终端,可能不行, 要计算一下带宽,可能要采用多服务器级连方案
 
后退
顶部