IcmpSendEcho,这个函数有数据限制吗?

时间:2014-04-03 17:29:13

标签: vb6

我在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

1 个答案:

答案 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