B服务器是Unix的,A还在继续向B发送数据包,但是B没有返回了,不知道
怎么回事

解决方案 »

  1.   

    有没有熟悉Unix下Socket通讯的仁兄,传授一点经验
      

  2.   

    To avay()我们现在也在怀疑这个问题,不知道有否方法可以增加缓冲区的大小,
    还有没有什么办法解决,谢谢先
    ePing
      

  3.   

    to bcb(天下三分明月夜,二分无赖是扬州) 靠,你就混到2颗星了,厉害有没有办法将可以清空Socket的缓冲区呀??
      

  4.   

    《unix网络编程上》说得很详细,具体怎样解决,我记不大清了。
      

  5.   

    大数据量测试一下B SERVER,是否有内存泄漏.
      

  6.   

    再问一个问题,象上面的测试环境,对于10000多笔交易出现了一次的
    返回信息失败,这属于正常吗?ePing
      

  7.   

    你用的是SCO unix还是AIX or Linux ?
      

  8.   

    你用的是SCO unix还是AIX or Linux ?
      

  9.   

    你试着更改scoadmin->hardware/kernel manager->parameter里的参数看看
      

  10.   

    to avay():
    刚才测试出是Unix仍然能够收到数据,但是负责发送数据到A的子进程起
    不来,我想这个可能和Socket没有关系了,这个原因是由于什么导致的
    你有没有这方面的经验??ePing
      

  11.   

    最省事的是kill掉后,重启B上的服务程序
      

  12.   

    to avay():
    这样可不行,我们现在正在测试,每次都是将近发了16000多条件交易,
    B就不能动了,Kill掉,重启,当然可以啦ePing
      

  13.   

    一条交易的数据量有多大,我怀疑buffer manager中的buffer cache参数是否过小
      

  14.   

    to avay()
    现在测试的交易的一条数据就来回200个字节,呵呵,很小的啦ePing
      

  15.   

    按你说得数据量和客户端发送时间间隔来看,不应该是 Server B 的buffer 溢出。
      

  16.   

    to errorcode(errorcode):
    同意你的想法,那你觉得会是那个地方出了毛病ePing
      

  17.   

    说不准,可能是 server B 内存有泄漏。
    如果每次都在16000的附近出问题,这种可能性就更大了。
    你查一下server B 的系统资源使用情况看看
      

  18.   

    借宝地问一个问题:
    在Windows环境下,用SOCKETS建一个Server,采用不阻塞的方式,我采用的
    是注册一个窗体来响应消息,但听说当用户量大的话窗体就不够用,如果用
    多线程的话,线程太多就开销太大(可能有10万用户),有什么方法解决
    这个问题。这里高手多,解决后保证重开贴子给分
    谢谢!
      

  19.   

    好像是什么资源耗尽后的现象,很久没有搞unix了,说不清。
      

  20.   

    建议你使用多线程,但是你没有必要为每一个客户请求新建一个服务线程。
    你可以建立一个线程池,线程池里面有N个线程,其中有一个线程负责调度工作,
    在任一时刻由另外的N-1个线程处理客户请求,如果某一时刻请求的个数大于线程个数,你就需要创建一个队列用于给这些请求排队,以决定谁先被调度给线程池处理,线程池的每一线程都有一个状态标记,以指示该线程处于忙或空闲状态,如果某个线程由忙转入空闲,则调度线程会检测当前队列中有无请求,如有,则调度线程会将此线程调度去处理队列中的请求。其实线程池的原理与电信局中的响应拨号
    用户上网的MODEM池的原理是相似的。
      

  21.   

    因为可以重复,所以应该不难解决。你可以采取下列步骤来找到问题所在:
    1。使问题出现;
    2。attach debugger到B服务进程;
    3。在网包接收调用(比如select或read system call)后的下一语句设断点;
    4。继续程序的执行;如果程序不运行到断点,那是通讯问题(包括缓冲已满),请看后面的关于通讯的分析;
    5。从段点处往下在debugger内执行,如果不是多线程程序,很容易找到问题所在。如果是多线程程序,就会复杂些,它和你的线程模型有关。一般来说,你可以通过设断点来跟踪新线程。通讯分析:
    打开(运行)network niffer(sniffer, TCP dump等)来跟踪从A到B的包。当问题出现时看包是否从A送到B。如果没有,而且网络没问题,那么很可能是B的缓冲已满,虽然A还能送(你说的),但它只是送到它的缓冲(再过一会它也会满,然后就不能再送了)。缓冲的加大不能从根本上解决你的问题,它只是推迟问题的出些。所以你不能依赖它。而缓冲溢出的根本原因是B比A慢。只有B比A快才能从根本上解决问题。缓冲只能在突发的大量服务请求是起点作用(缓冲该然后设置,最好找本UNIX performance tuning的书来看。它有大中小三类,合理分配才能起到大作用,瞎调无益)。
    如果包确实是从A送到B了,那么B的缓冲一定没满。
      

  22.   

    to ePing(三少):是否是A服务器的线程没有正常结束,导致A线程启的太多而终止了发送?
    因为一般来讲通讯资源不足是出在客户端的,而服务器端一般都能正常释放资源(除非你一直没有释放),我想你的unix机器应该是服务器端吧?测试unix下socket资源状态(netstat -p tcp),如果里面有很多Close_Wait,就不正常了!
      

  23.   

    我曾经遇到过这种大数据量传输中出现的停发包现象,有这样几种可能性。
    1.(客户端问题)
      包阻塞的情况多发生于缓冲区域充满了数据,客户端不再进行读取操作时。
      这种情况下,可能是由于客户端的处理节奏慢于接受包的速度,可以考虑
      将包处理过程放入线程处理,而对包的接受采用阻塞的方式。
    2.(服务器端问题)
      由于数据包头中部分变量的类型定义不合理而引起包的流水号越界或溢出,
      都可能导致服务器端出现core文件或异常停止。建议如果有在包头中定义
      流水号等,用long型变量。
    3.(协议包问题)
      在大数据量传输中,尽量减少网络资源的重复使用次数,所以在网络状况
      佳的情况下,建议将原有的包体长度适当的扩大。如2k扩大到30k左右,
      同时可以减少客户端的处理次数。
      

  24.   

    跟网络协议的缓冲区没有关系的。缓冲区是由操作系统的TCP/IP协议站掌管的。缓冲区溢出只能说明你的操作系统有问题?!缓冲区的大小,虽然可以设置,但只对效率有影响,不会出现停止等其他现象。你的server程序内部的缓冲区溢出倒是很有可能。你是不是使用大数组了?另外server程序可以加一些调试信息,比如select返回时输出信息,开始处理时输出信息,处理结束后输出信息,这样程序停滞后,通过最后的输出信息就能定位哪一步有问题了。对了你使用的是TCP吧?!
      

  25.   

    对于core dump,一般都是资源释放和越界或溢出问题。我觉的最大的可能是发生在你对线程的控制上面。我们曾在八路cpu的hp-ux上面碰到过类似的问题谨慎小心的使用线程
      

  26.   

    to badbird(badbird) 我只在2CPU的SUN工作站上开发过程序,没什么特别的?在八路cpu的hp-ux上开发程序是什么感觉?
      

  27.   

    出差去了,没想到有这么多朋友关注这个问题,
    多谢大家,希望能够继续讨论,往前推ePing
      

  28.   

    to elpam:
      大家可以继续讨论一下与之相关的问题嘛ePing
      

  29.   

    to:  harryliu($哈瑞@)我的意思是:在单CPU的系统上面,多线程是通过CPU时间分片来模拟的而在多路CPU的系统上面,是真正的多线程。
      

  30.   

    Unix下做的多线程Socket如果没有使用signal()来消除子进程的Socket连接的话,子连接不会自动释放,而是变成游离的无父进程的子进程,游离的进程太多就没有可以分配的进程号了。
    一般来说Unix下的Socket如果是多线程的最好采用端口复用,就是连接处理完毕以后把连接pooling起来而不是释放,下次再有连接到来的话取出给新的进程使用
    但是这个实在是比较复杂的技术,在这里没有办法完全写出来,建议你看看有一套共三卷的TCP/IP的书.
    我认为一个简单的处理是对fork出的子进程数量作个限定,超过限定的就等待有子进程完成对socket的操作,再吧这个子进程的socketID给新的子进程
      

  31.   

    是不是信号量在某处未能释放?
    我曾经碰到过,在一个特定分支continue 时忘了unlock
    另外,如果是用线程,须注意UNIX下线程结束时并不完全释放资源,当线程产生到一定量时,就再也不能产生了。在Solaris上试过,大概4000个线程
      

  32.   

    子进程即使变成僵尸进程(或称幽灵进程)后所有的file descriptor (当然包括socket descriptor)都会被关闭。如果线程是detached thread(分离线程?)它结束时资源会被自动回收。如果线程是用户线程,当正在运行的线程处于等待时,整个进程会处于等待状态而不是另一个用户线程运行。这是许多人不注意的地方。原因是用户线程不是scheduling entity所以schedule是按进程做的。而进程内部没有scheduling system所以在当前线程结束前不会换线程运行。从此也可以看出用户线程比系统线程需要的资源少,所以要合理地分配系统/用户线程。TCP/IP缓冲可能造成进/线程阻塞,如果socket是blocking mode而且缓冲满了,对socket的write operation就会阻塞。而如果此时另一端以把读缓冲清空了,它的read operation也会阻塞。
      

  33.   

    强烈推荐!强烈推荐全新的调查!
    强烈推荐!强烈推荐!强烈推荐全新的调查!
    强烈推荐!强烈推荐!强烈推荐!强烈推荐全新的调查,谢谢!http://www.csdn.net/Expert/TopicView1.asp?id=655336
      

  34.   

    我们换个角度考虑
    可能还是程序的问题
    我觉得有两种可能,就是b没有收到a的reply消息,或者是a没有收到b的reply消息
    查一下程序吧