在本机上用winsock控件向一个远端设备发命令,如果本机的网线被拔掉,我想让winsock自动重新发送没发送出去的指令,直到网线插上的时候,继续发送和接收。这个不难实现,可是我在我的电脑上试验成功,到了客户的机器上就不行了。在他的电脑上,只要拔出网线,再插上,程序就不好用了。
在这里请教一下:可能跟电脑的配置有关么?(我的电脑配置很高,客户的只是奔2-400的CPU),还有可能是什么问题(winsock的错误)?

解决方案 »

  1.   

    定时器负责定时用winsock向外发命令,如果拔了网线,会产生10065或者10049这两个错误(我只发现这两个),判断如果是这两个错误,退出,再下一个定时器事件重新发。程序在我的机器上一定是好用的。但是在客户的机器上,拔了网线再插上后,winsock不再向外发命令了。因为客户的机器没有VB,所以无法判断是什么问题。我猜测:
    1。机器配置太低
    2。网卡导致
    3。缓冲区但是,如果谁有新的想法可以多提一下,我实在想不出为什么不好用
      

  2.   

    在程序中适当位置加入debug.print err.number 吧!
    这样可以判断到底是哪个错误号!
      

  3.   

    //在程序中适当位置加入debug.print err.number 吧!
    这样可以判断到底是哪个错误号!给客户用还能debug?直接安装程序了。
      

  4.   

    首先要弄明白: 10065或者10049这两个错误 是由网卡硬件发出的,还是由WINSOCK发出的.如果是网卡发出的,那不同型号的网卡会不会有所不同呢.我觉得这和机器配置是不会有关系的,而在于你检测网络是否通的方法上.
    你可否在定时器中加语句,ping一下服务器地址(我指你要通讯的那台机器),
    如果ping通就说明网络连接好.如果不通就没有连接.
      

  5.   

    to:WallesCai(曾经沧海难为水,除却巫山不是云。此情可待成追忆,只是)用程序如何ping?
      

  6.   

    //我觉得这和机器配置是不会有关系的,而在于你检测网络是否通的方法上.
    你可否在定时器中加语句,ping一下服务器地址(我指你要通讯的那台机器),
    如果ping通就说明网络连接好.如果不通就没有连接.
    这个如果是问题,为什么平常的时候是正常的,一拔网线再安上就不好用了?说明对方网络应该没问题。我的程序在我机器上怎么拔网线都不要紧,所以说我怀疑跟机器有关。
      

  7.   

    Option ExplicitPrivate Const WS_VERSION_REQD = &H101
    Private Const WS_VERSION_MAJOR = WS_VERSION_REQD \ &H100 And &HFF&
    Private Const WS_VERSION_MINOR = WS_VERSION_REQD And &HFF&
    Private Const MIN_SOCKETS_REQD = 1
    Private Const SOCKET_ERROR = -1
    Private Const WSADescription_Len = 256
    Private Const WSASYS_Status_Len = 128
         
    Private Type HOSTENT
        hName As Long
        hAliases As Long
        hAddrType As Integer
        hLength As Integer
        hAddrList As Long
    End Type
         
    Private Type WSADATA
        wversion As Integer
        wHighVersion As Integer
        szDescription(0 To WSADescription_Len) As Byte
        szSystemStatus(0 To WSASYS_Status_Len) As Byte
        iMaxSockets As Integer
        iMaxUdpDg As Integer
        lpszVendorInfo As Long
    End Type
         
    Private Declare Function WSAGetLastError Lib "WSOCK32.DLL" () As Long
    Private Declare Function WSAStartup Lib "WSOCK32.DLL" (ByVal wVersionRequired&, lpWSAData As WSADATA) As Long
    Private Declare Function WSACleanup Lib "WSOCK32.DLL" () As Long
    Private Declare Function GetHostName Lib "WSOCK32.DLL" Alias "gethostname" (ByVal Hostname$, ByVal HostLen As Long) As Long
    Private Declare Function GetHostByName Lib "WSOCK32.DLL" Alias "gethostbyname" (ByVal Hostname$) As Long
    Private Declare Sub RtlMoveMemory Lib "KERNEL32" (hpvDest As Any, ByVal hpvSource&, ByVal cbCopy&)Public Enum UE_SocketsError
        se_NoErrors
        se_CouldNotFoundSocketsDLL
        se_SocketsDLLVersionError
        se_SocketsDLLVersionIsNotSupport
        se_SocketsAlreadyInCleanUp
        se_SocketsRunTimeError
    End Enum
         
    Public Type UDT_IPInformation
        Hostname                    As String
        IPCount                     As Long
        IPAddress()                 As String
        LastErrorNumber             As UE_SocketsError
        LastErrorMessage            As String
    End TypePublic Function GetIP() As UDT_IPInformation    Dim TempRtn As UDT_IPInformation, Hostname As String * 256, HostEnt_Addr As Long, Host As HOSTENT, HostIP_Addr As Long, Temp_IP_Address() As Byte, I As Integer, IP_Address As String
        
        TempRtn.LastErrorNumber = SocketsInitialize
        Select Case TempRtn.LastErrorNumber
            Case se_NoErrors
                TempRtn.LastErrorMessage = "函数成功!"
            Case se_CouldNotFoundSocketsDLL
                TempRtn.LastErrorMessage = "没有找到 Windows Sockets 动态连接库"
                GetIP = TempRtn
                Exit Function
            Case se_SocketsDLLVersionError
                TempRtn.LastErrorMessage = "Windows Sockets 版本错误"
                GetIP = TempRtn
                Exit Function
            Case se_SocketsDLLVersionIsNotSupport
                TempRtn.LastErrorMessage = "Windows Sockets 版本不支持本操作"
                GetIP = TempRtn
                Exit Function
            Case se_SocketsAlreadyInCleanUp
                TempRtn.LastErrorMessage = "Widnows Sockets 正在关闭"
                GetIP = TempRtn
                Exit Function
        End Select
        If GetHostName(Hostname, 256) = SOCKET_ERROR Then
            TempRtn.LastErrorNumber = se_SocketsRunTimeError
            TempRtn.LastErrorMessage = "Windows Sockets error " & Str(WSAGetLastError())
            GetIP = TempRtn
            Exit Function
        End If
        HostEnt_Addr = GetHostByName(Hostname)
        If HostEnt_Addr = 0 Then
            TempRtn.LastErrorNumber = se_SocketsRunTimeError
            TempRtn.LastErrorMessage = "Windows Sockets Runtime Error:WinSock.dll Is Not Responding"
            GetIP = TempRtn
            Exit Function
        End If
        RtlMoveMemory Host, HostEnt_Addr, LenB(Host)
        RtlMoveMemory HostIP_Addr, Host.hAddrList, 4
        TempRtn.Hostname = Left(Hostname, InStr(Hostname, Chr(0)) - 1)
        ReDim Preserve TempRtn.IPAddress(0)
        Do
            ReDim Temp_IP_Address(1 To Host.hLength)
            RtlMoveMemory Temp_IP_Address(1), HostIP_Addr, Host.hLength
            For I = 1 To Host.hLength
                IP_Address = IP_Address & Temp_IP_Address(I) & "."
            Next
            IP_Address = Mid$(IP_Address, 1, Len(IP_Address) - 1)
            ReDim Preserve TempRtn.IPAddress(UBound(TempRtn.IPAddress) + 1)
            TempRtn.IPAddress(UBound(TempRtn.IPAddress)) = IP_Address
            IP_Address = ""
            Host.hAddrList = Host.hAddrList + LenB(Host.hAddrList)
            RtlMoveMemory HostIP_Addr, Host.hAddrList, 4
        Loop While (HostIP_Addr <> 0)
        TempRtn.IPCount = UBound(TempRtn.IPAddress)
        GetIP = TempRtn
        SocketsCleanUpEnd FunctionPrivate Function HiByte(ByVal wParam As Integer)    HiByte = wParam \ &H100 And &HFF&End Function
         
    Private Function LoByte(ByVal wParam As Integer)    LoByte = wParam And &HFF&End Function
         
    Private Function SocketsInitialize() As UE_SocketsError
        
        Dim WSAD As WSADATA
        Dim iReturn As Integer
        Dim sLowByte As String, sHighByte As String, sMsg As String
        iReturn = WSAStartup(WS_VERSION_REQD, WSAD)
        If iReturn <> 0 Then
            SocketsInitialize = se_CouldNotFoundSocketsDLL
            Exit Function
        End If
        If LoByte(WSAD.wversion) < WS_VERSION_MAJOR Or (LoByte(WSAD.wversion) = WS_VERSION_MAJOR And HiByte(WSAD.wversion) < WS_VERSION_MINOR) Then
            sHighByte = Trim$(Str$(HiByte(WSAD.wversion)))
            sLowByte = Trim$(Str$(LoByte(WSAD.wversion)))
            'Windows_Sockets_Version = sLowByte & "." & sHighByte
            SocketsInitialize = se_SocketsDLLVersionError
            Exit Function
        End If
        If WSAD.iMaxSockets < MIN_SOCKETS_REQD Then
            SocketsInitialize = se_SocketsDLLVersionIsNotSupport
            Exit Function
        End If
        SocketsInitialize = se_NoErrorsEnd Function
         
    Private Function SocketsCleanUp() As UE_SocketsError    Dim lReturn As Long
        lReturn = WSACleanup()
        If lReturn <> 0 Then
            SocketsCleanUp = se_SocketsAlreadyInCleanUp
        Else
            SocketsCleanUp = se_NoErrors
        End IfEnd Function在你每次需要发送你的命令前调用GetIP这个函数,得到的UDT_IPInformation中的IPCount如果大于0,则你继续发送,如果=0,则所有的网卡都断开连接了,这是你就没有必要再发送了,这时你需要每隔一段时间运行一次GetIP判断是否有网卡恢复连接,如果有就继续发送。这是我在一个多网卡机器上用于获得每个网卡的IP的程序,你删除其中对你没有用的代码即可。
      

  8.   

    to NewViewStudio(傻鱼):谢谢你的代码,但是如果网卡与系统的连接是好的,即使拔掉网线IPCount也是>0的,所以对于我来说,网线查拔的判断还是没能解决。
      

  9.   

    一个不成熟的想法:楼主是不是可以看看网络本身的问题,比如你的ip地址是固定的,这样即使你把网线拔了,应该ip也不会变。客户的机子是不是动态ip,所以你把网线拔了,他的ip都没有了,所以再插上就没有反应了:)
      

  10.   

    //在程序中适当位置加入debug.print err.number 吧!
    这样可以判断到底是哪个错误号!给客户用还能debug?直接安装程序了。
    =========================
    安装程序后再调试也不是不可能的问题是要在你的程序里添加多一些代码
    例如,可以让的exe文件带参数启动,当启动参数是-debug时,程序就以调试的模式运行,这时可以直接在用几个lable显示winsock的状态等等关键的数据以帮你分析问题的所在。如果嫌这样子不好也可以干脆把错误信息,关键数据等保存到一个文本文件再慢慢分析
    当然,如果程序启动时没有参数过参数不是debug,则程序以正常状态运行。。
      

  11.   

    to BugBright(BUG亮) :
    谢谢提供想法,这个早就已经想过,可惜客户机已经是固定IP,所以不存在这个问题。to lsftest():
    这个想法我已经付诸实现了,准备下次去客户那里试试,谢谢。
      

  12.   

    to lsftest():
    这个想法我已经付诸实现了,准备下次去客户那里试试,谢谢。
    ================================
    关于生成exe后的调试,还有一个更彻底的办法,就是在程序里添加一个scriptcontrol和两个隐藏的textbox,其中一个textbox用来输入想要程序动态执行的代码,例如显示winsock的状态等,另一个就显示结果动态语句的执行结果不过如果程序一切正常,这些就变得是多余了楼主看着办吧