通信算法问题?来者有分,高手请进!

ISAKEEPER 2003-09-02 09:57:44
不好意思,又重提老问题。通信代码是点对多型服务器端和客户端,服务器端的发送线程从发送数据链表中取头元素后,把它发送到所有连接了服务器的客户端。采用两个线程,一个发送线程和一个主线程(接受函数在里面)。因本系统是电力系统的采集系统,所以服务器总是有实时数据传入,即发送线程总是工作的。为了在LAN保障数据的可靠通信,采用一个简单的校验,到客户端收到数据校验后,再向服务器发送一个信息(决定是否需重发),服务器再根据此信息来维护发送数据链表和发送数据备份链表。
我现在采取的算法是:客户端端收到某一数据包后,向服务器发送一个信息(‘N’+该数据包的流水号)当服务器第一次收到某一个特定的信息头后(如“N”),把它后面的流水号赋给一个全局变量,再把下次收到的改类型的流水号与第一个比较,相等就把计数变量加1,当计数变量等于了客户连接链路的元素后,则从数据发送链表中删除此元素,以及相应的发送数据备份链表中的元素。
上面的算法目前还是有点问题:对于某个数据包,如果客户端只有部分或没有根本没有返回信息,则服务端不能删除发送数据链表中的元素,这样这个元素占有的内存就永远不能释放,因此发生多次这样的问题,系统资源将受到影响。请问大家怎样改进这个算法?

运行状态:
如果是一个客户端与服务器连接时,服务器端能够处理过来,代码占有的内存数为4,476K,但当再加入一个客户端,代码占有服务器的内存会不端的增大,运行几个小时,就会把内存耗完。目前我估计主要是由于上述算法而致,因为代码内存泄漏方面自己用了BoundsChecker没有检测到内存泄漏的错误,另外我的发送数据链表内容没有用到指针。

问题:请问大家怎样改进这个算法?谢谢!

...全文
58 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
ISAKEEPER 2003-09-08
  • 打赏
  • 举报
回复
TO rtdb():您好
我局部修改了一下,现在还是不行,所以还是可能要按照您的算法,来实现了 :)
您的提示,“最好是每个客户端建一个管理类, 自已管理自已的链表,并有一个自已的发送线程。 主线程接收到数据后, 更新状态到客户管理类就可以了”,对于您提示,我仍有几点不清楚,请您再次指点:
1)是否事先要做到,每对应于一个客户端,就建立好一个数据链表;比如原来是10 个用户,不久又增加一个用户,这时是不是要人为的添加一个数据链表。
2)主线程接收到了数据后,这里是不是主线程OnReceive()信息后,再转到不同客户端的处理程序。如果是的话,这里怎样才能做到识别数据来自不同的客户端,再去维护相应的线程的数据链表
3)“主线程接收到数据后, 更新状态到客户管理类就可以了”能不具体解释一下
谢谢!
rtdb 2003-09-08
  • 打赏
  • 举报
回复
1) 关于用户管理,一般有两种方式:
固定模式:应有一个配置文件,启动时读入。若有修改或增加, 需更新配置文件,重新启动
动态模式: 客户有一个类似LOGIN的过程, 发现是新客户, 就新增一个客户类来管理它。

2,3) 不管是用IP地址也好, 包头标识也好, 服务器必须能区分出收到的包来自哪一个客户。这是多客户时最基本的要求。这一点若是作不到,任何管理方式都无从谈起。你原来的方案无效可能也是这个原因。

另外, 若是TCP通信, 一般没必要自己管理重发等。
若是可恢复错误, TCP内有纠错机制, 不用你管;
真是出错了, 重发基本上也没有用处。

feeboby 2003-09-06
  • 打赏
  • 举报
回复
学习
ProgrameMan 2003-09-06
  • 打赏
  • 举报
回复
http://www0.ccidnet.com/tech/paper/2001/10/17/58_3443.html
ProgrameMan 2003-09-06
  • 打赏
  • 举报
回复
http://www.nbcai.org/forums/cpbasedudp.htm
mqbwx 2003-09-06
  • 打赏
  • 举报
回复
共同学习!
ISAKEEPER 2003-09-06
  • 打赏
  • 举报
回复
大侠:
“参考TCP协议的滑动窗口算法的实现”请哪里有这方面的资料下呀
ProgrameMan 2003-09-05
  • 打赏
  • 举报
回复
同意 xuying 的看法
ProgrameMan 2003-09-05
  • 打赏
  • 举报
回复
参考TCP协议的滑动窗口算法的实现。<TCP/IP详解>
rtdb 2003-09-05
  • 打赏
  • 举报
回复
我建议你改一下设计:

最好是每个客户端建一个管理类, 自已管理自已的链表,
并有一个自已的发送线程。
因为事实上也是可以同时发送的
(若是硬件不允许就另当别论了)

主线程接收到数据后, 更新状态到客户管理类就可以了。

针对每个客户, 发送确认,超时检查等等操作就很好处理了。
ISAKEEPER 2003-09-04
  • 打赏
  • 举报
回复
TO rtdb():您好!
如果我想对那些客户端,没有返回收到数据报信息的的客户端(有部分客户端返回了),重发数据报的话,有什么好办法啊 :)

因为我目前的代码是只有一个发送线程,接受函数在主线程中,所以自己现在还没想到一个好的办法来确认哪些客户端,没有返回信息,请大家指点!
ISAKEEPER 2003-09-04
  • 打赏
  • 举报
回复
不好意思,这两天学校网络不通,所以没有及时上来
所有用户使用一个发送链表,对所有的链表使用了同步化;另外整个代码都用了一个发送线程。
rtdb 2003-09-03
  • 打赏
  • 举报
回复
呵呵, 整个算法有再优化的必要。

若只是局部改进,解决“服务端不能删除发送数据链表”的问题,
使用超时检查就可以了。 设一计时器, 记录最后一个数据包到达时间,
若超时(比如十分钟)还没有收到下一个包, 就可以放弃全部数据了。

超时检查在通信中是十分常用的方法, 可多加利用。


你的算法有点没说清楚的地方:
我想你是针对每个客户建一个发送(或接收)链表。
使用全局变量, 可能导致两个客户的链表冲突。

海洋hk 2003-09-02
  • 打赏
  • 举报
回复
把数据包编号,一个个发送,客户端受到后,返回N,从服务端的表中把这个包删掉
这样等所有的包都删掉就是传完了

你用的那种等个数一致再删,不对,而且有问题

最好你想一个链表装数据包,一个个删就行了,等链表空了就完事,还挺简单的
wuxuan 2003-09-02
  • 打赏
  • 举报
回复
最好在你完成一次消息通信后,实现一次握手,确认数据的准确性,如果没有收到这个确认包,就可以释放相应的元素。


jennifergiant 2003-09-02
  • 打赏
  • 举报
回复
up
elxf99 2003-09-02
  • 打赏
  • 举报
回复
UP
dhyuser10 2003-09-02
  • 打赏
  • 举报
回复
学习
ISAKEEPER 2003-09-02
  • 打赏
  • 举报
回复
不好意思,补充一下,发送线程的内容:
发送线程中数据是从数据发送链表中取头元素,然后向所有用户连接链表中的元素,发送数据,发送完后,再从取第二个元素,重复第一的内容。数据接收线程和发送线程目前没有什么关联,各做各的事情。

如果数据发送一次以后,在第二次数据发送之前,要以第一次发送数据后接收到的客户端返回的信息,作为条件的话,不知最好怎样定义好这个条件,请大家指点,谢谢!
xuying 2003-09-02
  • 打赏
  • 举报
回复
参考TCP协议的滑动窗口算法的实现。<TCP/IP详解>

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧