最近新做了一个项目,基于CS结构的服务器客户端程序。
 我做了一个简单的检测程序,开了虚拟的机器人客户端,在没隔0.5秒给服务器发报文,然后服务器
 将此报文广播给所有在线的其他客户端,但是在服务器的连接客户端到了400个左右就出现了错误。
 
 具体错误是:10055
 由于系统缓冲区空间不足或列队已满,不能执行套接字上的操作。 
 
 请问一下像这样的问题怎样解决?是我的程序内存泄漏造成的缓冲区不足,还是通讯上收发
 处理不过来了,造成发送队列缓冲以满呢? 在线等待,谢谢大家了

解决方案 »

  1.   

    我将SOCKET的缓冲区改大了试过了,是没有作用的,我发现是系统的缓冲区满了在一些关于释放资源的代码我是在检查,但现今没有发现问题
    我查阅了一些资料:
    MICROSOFT是这样提到的:
    Because TCP/IP system doesn't free sockets immediately when they are closed (socket remains allocated for 240 seconds after application closes it) it is possible that system will report WSAENOBUFS due to lack of free socket resources.
    如果是这样的话,资源在240秒后被释放,就算我的程序有内存泄漏,可能也不是主要的原因吧我是在测试服务器的承载能力,客户端是不会关闭套结子的,但是服务器的承载能力也不会底到
    只有400吧MICROSOFT都说WIN2KSERVER一个PORT可以建立5000以上个连接呢
      

  2.   

    你可以看看MSDN中OOB(Out-of-Band)的相关内容。
      

  3.   

    SOCKET,系统是有限制的,但是具体多少个不清楚,没有测试过。
    感觉还是你整体控制问题,找找看流程是否有问题。
      

  4.   

    我看了MS的文档,在WIN2000上SOCKET可以建立5000个连接只要有消息到达,服务器一定是做了处理的,不会堆积的,我想CPU是足够用的。数据量比较多,队列满了这个可能我也想过,但是我增大了SOCK的缓冲区,都是没有用的我刚才又做了测试,我在代码上审视了好久,优化了好久,最后还是400个客户端左右就死掉了。
      

  5.   

    我一直在审视我的代码,请问一下有谁在测试程序时发现过这个问题?是怎么检查的?一般情况下什么样的代码错误会导致这样的错误?如果是内存泄漏的话,在CLOSE的同时,系统是不会释放内存的,MS说在大概240秒会释放这些内存的怎么办?
      

  6.   

    我哭啊,我查了好多资料CSDN也有好多这样类似的问题,不是客户端缓冲区满就是服务器缓冲区满但是就是没有一个帖子能解决的啊。是不是这个问题就真的没有办法解决了呢?有没有人见过类似的问题最后解决掉了,到底是怎么回事呢?
      

  7.   

    注意套接字的回收利用,使用AcceptEx 代替 accept 或者 WSAAccept  函数, 因为AcceptEx 可以把关闭的套接字回收利用,并不是把他从内存里删除掉 ,而是在下次连接中再次使用。
    好像 创建套接字 和 删除套接字很耗资源的。
      

  8.   

    请教一个网络通讯缓冲区空间不足或队列以满的错误 
    ------------------------------------------
    如果排除基本的编程问题,一般情况是多次调用send的原因,造成系统缓冲满了。解决的根本办法是在每次发送后,判断是否真的发完了。发完了以后再发,就永远不会有这种错了。
    但是这种方法有一个问题,就是当网络状况不好的情况,发的太快,收的慢的话,容易发生交通堵塞。不过,用程序控制的好的话,还是可以的。
      

  9.   

    很明显: client ,server 都有问题
    因为,client send()---后服务器收到OnReceive()---recv() 然后send() to all connectionclient
    这个过程一定要明确; client server 都要判断send() 和recv()是否接收完毕;
      

  10.   

    不要用一个Socket接收太多连接
      

  11.   

    如果只是一个转发过程。那么,你是不能让,这个中转s停止收发的。当你收到一份报文的时候,应把他缓存起来,然后,丢给线程池转发给每个客户端。注意,这个包可能还没有发出给每个client(部分),当第二个报文已经被中转s收到。--------->转发队列(控制长度,这是保障s的效率)上述过程是很容易产生的,因为,就象有些人回复中说道的,中转的带宽是很大的一般。但是你不能保证,每个client也很大,这样就容易产生,client收不及。当某一个client长期收不及,你应shudonw这个client。这样可以大大提高效率,占用少的线程。