不好意思,又重提老问题。通信代码是点对多型服务器端和客户端,服务器端的发送线程从发送数据链表中取头元素后,把它发送到所有连接了服务器的客户端。采用两个线程,一个发送线程和一个主线程(接受函数在里面)。因本系统是电力系统的采集系统,所以服务器总是有实时数据传入,即发送线程总是工作的。为了在LAN保障数据的可靠通信,采用一个简单的校验,到客户端收到数据校验后,再向服务器发送一个信息(决定是否需重发),服务器再根据此信息来维护发送数据链表和发送数据备份链表。
   我现在采取的算法是:客户端端收到某一数据包后,向服务器发送一个信息(‘N’+该数据包的流水号)当服务器第一次收到某一个特定的信息头后(如“N”),把它后面的流水号赋给一个全局变量,再把下次收到的改类型的流水号与第一个比较,相等就把计数变量加1,当计数变量等于了客户连接链路的元素后,则从数据发送链表中删除此元素,以及相应的发送数据备份链表中的元素。
    上面的算法目前还是有点问题:对于某个数据包,如果客户端只有部分或没有根本没有返回信息,则服务端不能删除发送数据链表中的元素,这样这个元素占有的内存就永远不能释放,因此发生多次这样的问题,系统资源将受到影响。请问大家怎样改进这个算法?运行状态:
如果是一个客户端与服务器连接时,服务器端能够处理过来,代码占有的内存数为4,476K,但当再加入一个客户端,代码占有服务器的内存会不端的增大,运行几个小时,就会把内存耗完。目前我估计主要是由于上述算法而致,因为代码内存泄漏方面自己用了BoundsChecker没有检测到内存泄漏的错误,另外我的发送数据链表内容没有用到指针。问题:请问大家怎样改进这个算法?谢谢!

解决方案 »

  1.   

    参考TCP协议的滑动窗口算法的实现。<TCP/IP详解>
      

  2.   

    TO rtdb():您好!
    如果我想对那些客户端,没有返回收到数据报信息的的客户端(有部分客户端返回了),重发数据报的话,有什么好办法啊 :)  因为我目前的代码是只有一个发送线程,接受函数在主线程中,所以自己现在还没想到一个好的办法来确认哪些客户端,没有返回信息,请大家指点!
      

  3.   

    参考TCP协议的滑动窗口算法的实现。<TCP/IP详解>
      

  4.   

    大侠:
    “参考TCP协议的滑动窗口算法的实现”请哪里有这方面的资料下呀
      

  5.   

    http://www.nbcai.org/forums/cpbasedudp.htm
      

  6.   

    http://www0.ccidnet.com/tech/paper/2001/10/17/58_3443.html
      

  7.   

    TO rtdb():您好
    我局部修改了一下,现在还是不行,所以还是可能要按照您的算法,来实现了 :)
    您的提示,“最好是每个客户端建一个管理类, 自已管理自已的链表,并有一个自已的发送线程。 主线程接收到数据后, 更新状态到客户管理类就可以了”,对于您提示,我仍有几点不清楚,请您再次指点:
    1)是否事先要做到,每对应于一个客户端,就建立好一个数据链表;比如原来是10 个用户,不久又增加一个用户,这时是不是要人为的添加一个数据链表。
    2)主线程接收到了数据后,这里是不是主线程OnReceive()信息后,再转到不同客户端的处理程序。如果是的话,这里怎样才能做到识别数据来自不同的客户端,再去维护相应的线程的数据链表
    3)“主线程接收到数据后, 更新状态到客户管理类就可以了”能不具体解释一下
    谢谢!
      

  8.   

    1) 关于用户管理,一般有两种方式:
       固定模式:应有一个配置文件,启动时读入。若有修改或增加, 需更新配置文件,重新启动
       动态模式: 客户有一个类似LOGIN的过程, 发现是新客户, 就新增一个客户类来管理它。 2,3) 不管是用IP地址也好, 包头标识也好, 服务器必须能区分出收到的包来自哪一个客户。这是多客户时最基本的要求。这一点若是作不到,任何管理方式都无从谈起。你原来的方案无效可能也是这个原因。另外, 若是TCP通信, 一般没必要自己管理重发等。
    若是可恢复错误, TCP内有纠错机制, 不用你管;
    真是出错了, 重发基本上也没有用处。