在本机上用winsock控件向一个远端设备发命令,如果本机的网线被拔掉,我想让winsock自动重新发送没发送出去的指令,直到网线插上的时候,继续发送和接收。这个不难实现,可是我在我的电脑上试验成功,到了客户的机器上就不行了。在他的电脑上,只要拔出网线,再插上,程序就不好用了。
在这里请教一下:可能跟电脑的配置有关么?(我的电脑配置很高,客户的只是奔2-400的CPU),还有可能是什么问题(winsock的错误)?
在这里请教一下:可能跟电脑的配置有关么?(我的电脑配置很高,客户的只是奔2-400的CPU),还有可能是什么问题(winsock的错误)?
1。机器配置太低
2。网卡导致
3。缓冲区但是,如果谁有新的想法可以多提一下,我实在想不出为什么不好用
这样可以判断到底是哪个错误号!
这样可以判断到底是哪个错误号!给客户用还能debug?直接安装程序了。
你可否在定时器中加语句,ping一下服务器地址(我指你要通讯的那台机器),
如果ping通就说明网络连接好.如果不通就没有连接.
你可否在定时器中加语句,ping一下服务器地址(我指你要通讯的那台机器),
如果ping通就说明网络连接好.如果不通就没有连接.
这个如果是问题,为什么平常的时候是正常的,一拔网线再安上就不好用了?说明对方网络应该没问题。我的程序在我机器上怎么拔网线都不要紧,所以说我怀疑跟机器有关。
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的程序,你删除其中对你没有用的代码即可。
这样可以判断到底是哪个错误号!给客户用还能debug?直接安装程序了。
=========================
安装程序后再调试也不是不可能的问题是要在你的程序里添加多一些代码
例如,可以让的exe文件带参数启动,当启动参数是-debug时,程序就以调试的模式运行,这时可以直接在用几个lable显示winsock的状态等等关键的数据以帮你分析问题的所在。如果嫌这样子不好也可以干脆把错误信息,关键数据等保存到一个文本文件再慢慢分析
当然,如果程序启动时没有参数过参数不是debug,则程序以正常状态运行。。
谢谢提供想法,这个早就已经想过,可惜客户机已经是固定IP,所以不存在这个问题。to lsftest():
这个想法我已经付诸实现了,准备下次去客户那里试试,谢谢。
这个想法我已经付诸实现了,准备下次去客户那里试试,谢谢。
================================
关于生成exe后的调试,还有一个更彻底的办法,就是在程序里添加一个scriptcontrol和两个隐藏的textbox,其中一个textbox用来输入想要程序动态执行的代码,例如显示winsock的状态等,另一个就显示结果动态语句的执行结果不过如果程序一切正常,这些就变得是多余了楼主看着办吧