Private Sub UserListen_ConnectionRequest(ByVal requestID As Long)
    '寻找空闲的usersock
    Dim Index As Long
    Dim ii As Long
    For Index = 0 To MaxDSClient
        If Index = MaxUserClient Then updata_data = Format(Now, "yy-mm-ss hh:mm:ss") & "→服务器:服务器分配用户的连接已经分配完毕,将不会接受新的用户连接。": updata_serverList
        If Me.UserClient(MaxUserClient).State <> 0 Then updata_data = Format(Now, "yy-mm-ss hh:mm:ss") & "服务器:用户连接超过最大连接数,如果需要创建更多连接请修改系统设置,然后重启服务器。": updata_serverList: Exit Sub
        If UserClient(Index).State = 0 Then
            UserClient(Index).Accept requestID
            UserClient(Index).Tag = Format(Now, "yyyymmddhhmmss")
            For usersock_state = 0 To MaxUserClient
                If UserClient(usersock_state).State <> 0 Then
                    If UserClient(usersock_state).RemoteHostIP = UserClient(Index).RemoteHostIP And UserClient(usersock_state).Tag < UserClient(Index).Tag Then
                        UserClient(usersock_state).Close
                        updata_data = Format(Now, "yy-mm-ss hh:mm:ss") & "→服务器:存在两个连接IP相同的用户,服务器将关闭早期的连接" & "|" & UserClient(Index).RemoteHostIP
                        updata_serverList
                    End If
                End If
            Next
            Exit For
        End If
    Next
    'DoEvents
End Sub
以上为服务器监听代码!我现在碰到原因是在内部光纤的情况下!超过80个TCP客户端同时连接服务器监听端口时软件服务器会出现卡死的状态。请问下是监听端口连接的卡死还是接收客户端信息口的卡机?tcp服务器

解决方案 »

  1.   

    服务器:服务器分配用户的连接已经分配完毕,将不会接受新的用户连接。": updata_serverList
    这儿怎么不退出呢: exit sub
      

  2.   

     For Index = 0 To MaxDSClient 第一个 For有什么用处?第二个 For usersock_state = 0 To MaxUserClient 有没有更好的方法查找呢?每次连接到MaxUserClient,是不是费时哦
      

  3.   

    第一个for 的作用就是给DSClient(Index)数组提供Index的值。每个都不会连接到最大值,当执行For 循环找到空闲或之前存在的值时for循环就会停止了!所以也不是很费时吧?
      

  4.   

    感觉你的程序还是有小问题,打比如,连接第一个和连接最后一个的IP地址相同,最后一次把最先一次close,其实还是空一个连接出来了,还可以再一个用户connect进来,而你的If Me.UserClient(MaxUserClient).State <> 0 就退出来,不允许连接了,不知道我的说法是否正确?
      

  5.   

    先不说你的程序是否有问题,就你选择用VB来做这种服务程序就存在很大的问题。
    如果要开发这种网络服务程序,建议换成 C/C++ 采用多线程或 IOCP 的方案来实现,VB+WinSock控件这个架构本来问题就很多,当玩具还可以,要抗压,根本不可能,你程序写得再好都是没用的,这一块是VB的软肋。
      

  6.   

    是啊,我也一直知道这个问题!VB做网络服务一直就不太行!但我这也没办法,公司不是专门做软件的,我一来就是这么一个架构在这里!现在要我一个人在短期内重新开发一套C/C++多线程的软件是不现实,所以目前只能就是寻找好的解决办法了!
      

  7.   

    没办法的,网络服务程序本来就和普通的应用程序要求不一样,作为技术测试勉强可以用VB玩玩些理论,作为专业服务来用(这里的“专业”是指需求方面,如稳定性、安全性、抗压能力、性能、资源控制、效率需求等等),VB是不适合做这方面程序的,所以建议换方案或直接更改开发工具和技术。
    换方案,可以用 IIS+ASP+XMLHTTP+VB 来实现这种网络数据的传输,因为服务程序借助的是现成的专业服务程序,通过服务器脚本识别远程请求来上传下载数据,稳定性和性能等需求都有一定的保障,而客户端直接用现成的系统对象来访问,简化了操作,同时也提高了开发效率。
    如果换开发工具,意味着你要有一定的网络开发方面基础,并且有能满足专业需求并可行的架构方案,如IOCP、过滤驱动、NT服务、程序配置等相关技术以及架构方案和现成模块等,如果没有这些东西,开发起来工程量会很大,而且稳定性、抗压能力、资源管控等都未必能得到改善,毕竟要搞个专业的网络服务程序不是个简单的事情,用VB来弄太儿戏了,说这种弄法是玩具级别的都高抬他了。
      

  8.   

    这是因为你还没有正真接触过网络服务这种东西,对于专业的网络服务程序而言,对于资源的使用和程序的效率是很讲究的,即使你用VC来开发,纯用 Sock API 和多线程来处理,如果架构和流程没弄好,同样会出现很多问题,特别是抗压力方面表现最为突出,更别说在 VB 里用控件来实现这种过程,抗压力肯定不足,甚至可以说 是完全没有抗压能力,如果不相信你可以用VB写个HTTP代理来看看,就本机访问你的代理去看几个网页,你就会发现VB连反应能力都是差很远的,绝对会丢失很多连接,网页上大部分图片都不会显示出来。你要知道,WinSock 控件是异步通讯的,也就是靠响应窗口消息来触发事件的,而且控件是有窗口的,你与每一个客户端连接的同时,就会建立一个控件来与其连接,除了控件的COM类和接口也会多一个窗口出来,并且还弄成ActiveX模型,而这个窗口同时还会有相应的处理函数过程,负责接收相关的消息和做出反应,网络消息也是依靠这种窗口来响应的。如果你的电脑同时开八九十窗口,并且每个窗口都还在等待或收发网络数据,对于内存、CPU的开销是多少你可以想像,而且这些过程还不是C语言那种简单的内存概念,还是VB的数据类型处理概念,要知道,VB的数据类型是标准的COM接口类型,就比如数组或String类型,如果在VC里处理这些类型的数据,需要调用专门的API和分配专门的结构体并且要先初始化COM环境才能使用,虽然在VB里使用起来很自然,但正真到了计算机运行,这些复杂的转换过程是漏不掉的,所以会进一步的拖慢程序的运行效率和内存使用量,而且VB程序通常是单线程的,多线程做这种东西根本不现实,难度比用VC写还大。因为除了要用VC Win32 SDK 的开发方案写线程函数过程,还要考虑 VB 数据类型以及相关结构的问题,最主要的还是很多VB本身的语句不能随意使用,因为新线程里没有这些资源供子线程使用,所以用VB写这种东西的多线程,难度比用VC写大很多,而且还不见得稳定。既然多线程不太可行,也就意味着用单线层跑的可能性很大,对于这么多窗口消息、这么多函数过程、这么多变量类型转换过程,系统还要处理别的优先级别更高的进程和线程,你认为这种程序效率会高到哪?从程序跑起来的内存,CPU使用量你就可以看出了,更别说每一个连接的反应能力和反应效率。虽然可以通过更换更高配置的硬件来改善一点这种情况,不过也只是掩耳盗铃的办法,解决不了根本的问题,如果你比较急于解决这种问题,可以给你两个方案:
    1、采用我上面说的IIS+ASP+XMLHTTP+VB的方案,有点类似于WEB开发上的AJAX技术来实现这种网络数据交换操作。
    2、项目外包,找个有实力的人或公司去弄网络服务这一块,你们自己写客户端。
    如果你不急于解决这种问题,你可以慢慢去研究C/C++语言网络服务程序开发这一块,熟悉了基础知识后,去研究架构,然后再开始慢慢实验和慢慢写。
    如果你留意一下会发现,在设备管理器里被影藏的项目中,会发现HTTP服务是做了驱动支持的,这就是MS的解决方案,而MS对外的解决方案是IOCP,虽然也不错,不过还是有软肋的,在这一块的架构上,要弄得好,自己还是要去弄过滤驱动的,虽然这种驱动并不难做,但对于搞应用开发的人来说,开始还是很花时间的,所以这一块真要深入,水可以说还是很深的,不会像VB做玩具那么简单,要自己做这块没有个心里准备是不行的。