我在VB6中调用了IcmpSendEcho来测试一个设备的以太网协议。 以太网的MTU是1500字节,所以我尝试发送1500字节,但VB6不允许我这样做。 它只允许我发送1014,当我发送1014个字节时,IcmpSendEcho给出了一般失败的错误。
当我发送250bytes时,它工作正常,但如果我发送超过250个字节,它会给我错误(一般失败)
我无法弄清楚问题所在。以太网协议可以处理多达1500个字节,但我的甚至不能达到250个字节。反正有没有调试或解决这个问题?
Private Declare Function IcmpSendEcho Lib "icmp.dll" _
(ByVal IcmpHandle As Long, _
ByVal DestinationAddress As Long, _
ByVal RequestData As String, _
ByVal RequestSize As Long, _
ByVal RequestOptions As Long, _
ReplyBuffer As ICMP_ECHO_REPLY, _
ByVal ReplySize As Long, _
ByVal Timeout As Long) As Long
Public Function ping(sAddress As String, Reply As ICMP_ECHO_REPLY) As Long
Dim hIcmp As Long
Dim lAddress As Long
Dim lTimeOut As Long
Dim StringToSend As String
Dim PingOutput As String 'Variable that shows Ping status
Dim Index As Integer
'Short string of data to send
'400byte
StringToSend = "ddd...." 'First of all I can't put more than 1014 characters in string.
'Secondly, "ddd..." is just example, putting 1014 will make it so messy
' I declared
'ICMP (ping) timeout
lTimeOut = 1000 'ms
'Convert string address to a long representation.
lAddress = inet_addr(sAddress)
If (lAddress <> -1) And (lAddress <> 0) Then
'Create the handle for ICMP requests.
hIcmp = IcmpCreateFile()
Do
If hIcmp Then
'Ping the destination IP address.
Call IcmpSendEcho(hIcmp, lAddress, StringToSend, Len(StringToSend), 0, Reply, Len(Reply), lTimeOut)
'Reply status
ping = Reply.Status
PingOutput = EvaluatePingResponse(ping)
If ping = 0 Then
Index = Index + 1
Else
MsgBox (PingOutput)
Exit Do
End If
'Close the Icmp handle.
'IcmpCloseHandle hIcmp
Else
Debug.Print "failure opening icmp handle."
ping = -1
End If
Loop Until (Index > 1000)
'Close the Icmp handle.
IcmpCloseHandle hIcmp
Else
ping = -1
End If
End Function
答案 0 :(得分:0)
您的代码无法立即运行,因此我必须从Win32文档中找出所有缺少的定义。你也在IcmpSendEcho()的定义中犯了一些错误。 RequestSize参数定义为:
_ In _ WORD RequestSize,
...这相当于VB6的Integer类型,而不是Long。
但是,主要问题可能与你没有为ReplyBuffer分配足够的空间有关。关于如何分配此缓冲区,您的示例中并不明显。该规范实际上要求一个ICMP_ECHO_REPLY数组,然后是额外的数据。为了确保这肯定有效,我创建了一个新类型,ReplyBuffer,并分配了比我需要的更多的空间:
Private Const m_knImcpEchoReplyCount As Long = 8
Private Const m_knReplyDataSize As Long = 4096
Public Type ReplyBuffer
IER(1 To m_knImcpEchoReplyCount) As IMCP_ECHO_REPLY
Data(1 To m_knReplyDataSize) As Byte
End Type
然后我在调用IcmpSendEcho()时传递 ReplyBuffer := uReplyBuffer.IER(1)和 ReplySize := LenB(uReplyBuffer)。
摆弄两个常数,直到你对此感到满意为止。您可能只需要将m_knImcpEchoReplyCount设置为1.对于m_knReplyDataSize,这需要大于您发送的最大字符串。
我的完整代码如下:
Option Explicit
Public Enum PingStatus
IP_SUCCESS = 0
IP_BUF_TOO_SMALL = 11001
IP_DEST_NET_UNREACHABLE = 11002
IP_DEST_HOST_UNREACHABLE = 11003
IP_DEST_PROT_UNREACHABLE = 11004
IP_DEST_PORT_UNREACHABLE = 11005
IP_NO_RESOURCES = 11006
IP_BAD_OPTION = 11007
IP_HW_ERROR = 11008
IP_PACKET_TOO_BIG = 11009
IP_REQ_TIMED_OUT = 11010
IP_BAD_REQ = 11011
IP_BAD_ROUTE = 11012
IP_TTL_EXPIRED_TRANSIT = 11013
IP_TTL_EXPIRED_REASSEM = 11014
IP_PARAM_PROBLEM = 11015
IP_SOURCE_QUENCH = 11016
IP_OPTION_TOO_BIG = 11017
IP_BAD_DESTINATION = 11018
IP_GENERAL_FAILURE = 11050
End Enum
Public Type IPAddr
s_b1 As Byte
s_b2 As Byte
s_b3 As Byte
s_b4 As Byte
End Type
Public Type IP_OPTION_INFORMATION
Ttl As Byte
Tos As Byte
Flags As Byte
OptionsSize As Byte
OptionsData As Long
End Type
Public Type IMCP_ECHO_REPLY
Address As IPAddr
Status As PingStatus
RoundTripTime As Long
DataSize As Integer
Reserved As Integer
Data As Long
Options As IP_OPTION_INFORMATION
End Type
Private Const m_knImcpEchoReplyCount As Long = 8
Private Const m_knReplyDataSize As Long = 4096
Public Type ReplyBuffer
IER(1 To m_knImcpEchoReplyCount) As IMCP_ECHO_REPLY
Data(1 To m_knReplyDataSize) As Byte
End Type
Private Declare Function IcmpSendEcho Lib "icmp.dll" _
(ByVal IcmpHandle As Long, _
ByVal DestinationAddress As Long, _
ByVal RequestData As String, _
ByVal RequestSize As Integer, _
ByVal RequestOptions As Long, _
ByRef ReplyBuffer As IMCP_ECHO_REPLY, _
ByVal ReplySize As Long, _
ByVal Timeout As Long) As Long
Private Declare Function inet_addr Lib "Ws2_32.dll" ( _
ByVal cp As String _
) As Long
Private Declare Function IcmpCreateFile Lib "Iphlpapi.dll" () As Long
Private Declare Function IcmpCloseHandle Lib "Iphlpapi.dll" (ByVal IcmpHandle As Long) As Long
Public Function Ping(sAddress As String, Reply As ReplyBuffer) As PingStatus
Dim hIcmp As Long
Dim lAddress As Long
Dim lTimeOut As Long
Dim StringToSend As String
Dim PingOutput As String 'Variable that shows Ping status Dim Index As Integer
Dim Index As Long
'Short string of data to send
'400byte
'StringToSend = "ddd...." 'First of all I can't put more than 1014 characters in string.
'Secondly, "ddd..." is just example, putting 1014 will make it so messy
' I declared
StringToSend = String$(2048, 32)
'ICMP (ping) timeout
lTimeOut = 1000 'ms
'Convert string address to a long representation.
lAddress = inet_addr(sAddress)
If (lAddress <> -1) And (lAddress <> 0) Then
'Create the handle for ICMP requests.
hIcmp = IcmpCreateFile()
Do
If hIcmp Then
'Ping the destination IP address.
Call IcmpSendEcho(hIcmp, lAddress, StringToSend, Len(StringToSend), 0, Reply.IER(1), LenB(Reply), lTimeOut)
'Reply status
Ping = Reply.IER(1).Status
PingOutput = EvaluatePingResponse(Ping)
If Ping = 0 Then
Index = Index + 1
Else
MsgBox (PingOutput)
Exit Do
End If
'Close the Icmp handle.
'IcmpCloseHandle hIcmp
Else
Debug.Print "failure opening icmp handle."
Ping = -1
End If
Loop Until (Index > 1000)
'Close the Icmp handle.
IcmpCloseHandle hIcmp
Else
Ping = -1
End If
End Function
Private Function EvaluatePingResponse(ByVal Ping As PingStatus) As String
Select Case Ping
Case IP_SUCCESS
EvaluatePingResponse = "The status was success."
Case IP_BUF_TOO_SMALL
EvaluatePingResponse = "The reply buffer was too small."
Case IP_DEST_NET_UNREACHABLE
EvaluatePingResponse = "The destination network was unreachable."
Case IP_DEST_HOST_UNREACHABLE
EvaluatePingResponse = "The destination host was unreachable."
Case IP_DEST_PROT_UNREACHABLE
EvaluatePingResponse = "The destination protocol was unreachable."
Case IP_DEST_PORT_UNREACHABLE
EvaluatePingResponse = "The destination port was unreachable."
Case IP_NO_RESOURCES
EvaluatePingResponse = "Insufficient IP resources were available."
Case IP_BAD_OPTION
EvaluatePingResponse = "A bad IP option was specified."
Case IP_HW_ERROR
EvaluatePingResponse = "A hardware error occurred."
Case IP_PACKET_TOO_BIG
EvaluatePingResponse = "The packet was too big."
Case IP_REQ_TIMED_OUT
EvaluatePingResponse = "The request timed out."
Case IP_BAD_REQ
EvaluatePingResponse = "A bad request."
Case IP_BAD_ROUTE
EvaluatePingResponse = "A bad route."
Case IP_TTL_EXPIRED_TRANSIT
EvaluatePingResponse = "The time to live (TTL) expired in transit."
Case IP_TTL_EXPIRED_REASSEM
EvaluatePingResponse = "The time to live expired during fragment reassembly."
Case IP_PARAM_PROBLEM
EvaluatePingResponse = "A parameter problem."
Case IP_SOURCE_QUENCH
EvaluatePingResponse = "Datagrams are arriving too fast to be processed and datagrams may have been discarded."
Case IP_OPTION_TOO_BIG
EvaluatePingResponse = "An IP option was too big."
Case IP_BAD_DESTINATION
EvaluatePingResponse = "A bad destination."
Case IP_GENERAL_FAILURE
EvaluatePingResponse = "A general failure. This error can be returned for some malformed ICMP packets."
End Select
End Function