Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Ping a server 1

Status
Not open for further replies.

steveblum

Programmer
Aug 6, 1999
55
US
Is there an API or another method to ping a server from VB.

I am using CreateObject with a remote server to call a DLL I wrote, but if the user gives the wrong server name, the CreateObject takes about a minute to raise an error. If I go to DOS and ping the name, I get my answer in a few seconds.

Does anyone know how to ping from VB, so I can speed up my app?

Thanks. [sig][/sig]
 
The author of the following is unknown, so I can't vouch for him as a person... but his code seems to work pretty well:
[tt]
Private Const IP_SUCCESS As Long = 0
Private Const IP_STATUS_BASE As Long = 11000
Private Const IP_BUF_TOO_SMALL As Long = (11000 + 1)
Private Const IP_DEST_NET_UNREACHABLE As Long = (11000 + 2)
Private Const IP_DEST_HOST_UNREACHABLE As Long = (11000 + 3)
Private Const IP_DEST_PROT_UNREACHABLE As Long = (11000 + 4)
Private Const IP_DEST_PORT_UNREACHABLE As Long = (11000 + 5)
Private Const IP_NO_RESOURCES As Long = (11000 + 6)
Private Const IP_BAD_OPTION As Long = (11000 + 7)
Private Const IP_HW_ERROR As Long = (11000 + 8)
Private Const IP_PACKET_TOO_BIG As Long = (11000 + 9)
Private Const IP_REQ_TIMED_OUT As Long = (11000 + 10)
Private Const IP_BAD_REQ As Long = (11000 + 11)
Private Const IP_BAD_ROUTE As Long = (11000 + 12)
Private Const IP_TTL_EXPIRED_TRANSIT As Long = (11000 + 13)
Private Const IP_TTL_EXPIRED_REASSEM As Long = (11000 + 14)
Private Const IP_PARAM_PROBLEM As Long = (11000 + 15)
Private Const IP_SOURCE_QUENCH As Long = (11000 + 16)
Private Const IP_OPTION_TOO_BIG As Long = (11000 + 17)
Private Const IP_BAD_DESTINATION As Long = (11000 + 18)
Private Const IP_ADDR_DELETED As Long = (11000 + 19)
Private Const IP_SPEC_MTU_CHANGE As Long = (11000 + 20)
Private Const IP_MTU_CHANGE As Long = (11000 + 21)
Private Const IP_UNLOAD As Long = (11000 + 22)
Private Const IP_ADDR_ADDED As Long = (11000 + 23)
Private Const IP_GENERAL_FAILURE As Long = (11000 + 50)
Private Const MAX_IP_STATUS As Long = (11000 + 50)
Private Const IP_PENDING As Long = (11000 + 255)
Private Const PING_TIMEOUT As Long = 500
Private Const WS_VERSION_REQD As Long = &H101
Private Const MIN_SOCKETS_REQD As Long = 1
Private Const SOCKET_ERROR As Long = -1
Private Const INADDR_NONE As Long = &HFFFFFFFF
Private Const MAX_WSADescription As Long = 256
Private Const MAX_WSASYSStatus As Long = 128

Private Type ICMP_OPTIONS
Ttl As Byte
Tos As Byte
Flags As Byte
OptionsSize As Byte
OptionsData As Long
End Type

Public Type ICMP_ECHO_REPLY
Address As Long
status As Long
RoundTripTime As Long
DataSize As Long 'formerly integer
'Reserved As Integer
DataPointer As Long
Options As ICMP_OPTIONS
Data As String * 250
End Type

Private Type WSADATA
wVersion As Integer
wHighVersion As Integer
szDescription(0 To MAX_WSADescription) As Byte
szSystemStatus(0 To MAX_WSASYSStatus) As Byte
wMaxSockets As Long
wMaxUDPDG As Long
dwVendorInfo As Long
End Type

Private Declare Function IcmpCreateFile Lib "icmp.dll" () As Long

Private Declare Function IcmpCloseHandle Lib "icmp.dll" _
(ByVal IcmpHandle As Long) As Long

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

Private Declare Function WSAGetLastError Lib "WSOCK32.DLL" () As Long

Private Declare Function WSAStartup Lib "WSOCK32.DLL" _
(ByVal wVersionRequired As Long, _
lpWSADATA As WSADATA) As Long

Private Declare Function WSACleanup Lib "WSOCK32.DLL" () As Long

Private Declare Function gethostname Lib "WSOCK32.DLL" _
(ByVal szHost As String, _
ByVal dwHostLen As Long) As Long

Private Declare Function gethostbyname Lib "WSOCK32.DLL" _
(ByVal szHost As String) As Long

Private Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" _
(xDest As Any, _
xSource As Any, _
ByVal nbytes As Long)

Private Declare Function inet_addr Lib "WSOCK32.DLL" _
(ByVal s As String) As Long


Public Function GetStatusCode(status As Long) As String

Dim msg As String

Select Case status
Case IP_SUCCESS: msg = "ip success"
Case INADDR_NONE: msg = "inet_addr: bad IP format"
Case IP_BUF_TOO_SMALL: msg = "ip buf too_small"
Case IP_DEST_NET_UNREACHABLE: msg = "ip dest net unreachable"
Case IP_DEST_HOST_UNREACHABLE: msg = "ip dest host unreachable"
Case IP_DEST_PROT_UNREACHABLE: msg = "ip dest prot unreachable"
Case IP_DEST_PORT_UNREACHABLE: msg = "ip dest port unreachable"
Case IP_NO_RESOURCES: msg = "ip no resources"
Case IP_BAD_OPTION: msg = "ip bad option"
Case IP_HW_ERROR: msg = "ip hw_error"
Case IP_PACKET_TOO_BIG: msg = "ip packet too_big"
Case IP_REQ_TIMED_OUT: msg = "ip req timed out"
Case IP_BAD_REQ: msg = "ip bad req"
Case IP_BAD_ROUTE: msg = "ip bad route"
Case IP_TTL_EXPIRED_TRANSIT: msg = "ip ttl expired transit"
Case IP_TTL_EXPIRED_REASSEM: msg = "ip ttl expired reassem"
Case IP_PARAM_PROBLEM: msg = "ip param_problem"
Case IP_SOURCE_QUENCH: msg = "ip source quench"
Case IP_OPTION_TOO_BIG: msg = "ip option too_big"
Case IP_BAD_DESTINATION: msg = "ip bad destination"
Case IP_ADDR_DELETED: msg = "ip addr deleted"
Case IP_SPEC_MTU_CHANGE: msg = "ip spec mtu change"
Case IP_MTU_CHANGE: msg = "ip mtu_change"
Case IP_UNLOAD: msg = "ip unload"
Case IP_ADDR_ADDED: msg = "ip addr added"
Case IP_GENERAL_FAILURE: msg = "ip general failure"
Case IP_PENDING: msg = "ip pending"
Case PING_TIMEOUT: msg = "ping timeout"
Case Else: msg = "unknown msg returned"
End Select

GetStatusCode = CStr(status) & " [ " & msg & " ]"

End Function



Public Function Ping(sAddress As String,
sDataToSend As String,
ECHO As ICMP_ECHO_REPLY) As Long

'If Ping succeeds :
'.RoundTripTime = time in ms for the ping to complete,
'.Data is the data returned (NULL terminated)
'.Address is the Ip address that actually replied
'.DataSize is the size of the string in .Data
'.Status will be 0
'
'If Ping fails .Status will be the error code

Dim hPort As Long
Dim dwAddress As Long

'convert the address into a long representation
dwAddress = inet_addr(szAddress)

'if a valid address..
If dwAddress <> INADDR_NONE Then

'open a port
hPort = IcmpCreateFile()

'and if successful,
If hPort Then

'ping it.
Call IcmpSendEcho(hPort, _
dwAddress, _
sDataToSend, _
Len(sDataToSend), _
0, _
ECHO, _
Len(ECHO), _
PING_TIMEOUT)

'return the status as ping succes and close
Ping = ECHO.status
Call IcmpCloseHandle(hPort)

End If

Else:
'the address format was probably invalid
Ping = INADDR_NONE

End If

End Function


Public Sub SocketsCleanup()

If WSACleanup() <> 0 Then
MsgBox &quot;Windows Sockets error occurred in Cleanup.&quot;, vbExclamation
End If

End Sub


Public Function SocketsInitialize() As Boolean

Dim WSAD As WSADATA

SocketsInitialize = WSAStartup(WS_VERSION_REQD, WSAD) = IP_SUCCESS

End Function

'--end block--'


Form Code

To a form add a command button (Command1),
two text boxes (Text1, Text2) to the top of the form,
and six text boxes in a control array (Text4(0) - Text4(5)) below.
The labels are optional. Add the following to the form:


Option Explicit

Private Sub Command1_Click()

Dim ECHO As ICMP_ECHO_REPLY
Dim pos As Long
Dim success As Long

If SocketsInitialize() Then

'ping the ip passing the address, text
'to send, and the ECHO structure.
success = Ping((Text1.Text), (Text2.Text), ECHO)

'display the results
Text4(0).Text = GetStatusCode(success)
Text4(1).Text = ECHO.Address
Text4(2).Text = ECHO.RoundTripTime & &quot; ms&quot;
Text4(3).Text = ECHO.DataSize & &quot; bytes&quot;

If Left$(ECHO.Data, 1) <> Chr$(0) Then
pos = InStr(ECHO.Data, Chr$(0))
Text4(4).Text = Left$(ECHO.Data, pos - 1)
End If

Text4(5).Text = ECHO.DataPointer

SocketsCleanup

Else

MsgBox &quot;Windows Sockets for 32 bit Windows &quot; & _
&quot;environments is not successfully responding.&quot;

End If

End Sub
[/tt]


[sig]<p> <br><a href=mailto: > </a><br><a href= plain black box</a><br>Don't sit down. It's time to dig another one.[/sig]
 
Wow, it's amazing how the API lets you write such concise code. :)


[sig]<p> Jonathan<br><a href=mailto:j.w.george@virginnet.co.uk>j.w.george@virginnet.co.uk</a><br><a href= > </a><br>Working against: Visual Basic 6, Access 97, Visual Interdev 6, VBScript, Active Server Pages, SQL Server 6.5, Oracle 7[/sig]
 
Jonathan, I assume that contained a touch of sarcasm. I have never found anything &quot;concise&quot; about the API. But once you have made the declarations and tucked the spaghetti away in a module it becomes pretty darn reusable. |-0 [sig]<p> <br><a href=mailto: > </a><br><a href= plain black box</a><br>"For most users of personal computers, the single-user, single task restrictions are of no consequence. Personal computers work just fine with one console."<br>
<b><u>CP/M and the Personal Computer</u></b>[/sig]
 
You're right, there was an element of sarcasm in there, but it wasn't directed at your code. I just find the amount of code above quite amusing when compared against the dos &quot;ping&quot; command...
[sig]<p> Jonathan<br><a href=mailto:j.w.george@virginnet.co.uk>j.w.george@virginnet.co.uk</a><br><a href= > </a><br>Working against: Visual Basic 6, Access 97, Visual Interdev 6, VBScript, Active Server Pages, SQL Server 6.5, Oracle 7[/sig]
 
Jonathon,

I've never seen the source for the &quot;dos&quot; ping command but the source for the Unix ping command looks quite similar.

And you could, of course, use the above code to make your own, perhaps specialised, ping command... [sig]<p>Mike<br><a href=mailto:michael.j.lacey@ntlworld.com>michael.j.lacey@ntlworld.com</a><br><a href= Cargill's Corporate Web Site</a><br>[/sig]
 
I've used the code you provided to write a class object. It works great, but there is one thing I don't understand. When a server is not found, IP_BAD_DESTINATION is returned, as expected. But when a server is found, the response is IP_REQ_TIMED_OUT. I'm not sure why I get a timeout instead of IP_SUCCESS.

Right now I just have my program written such that if I get IP_BAD_DESTINATION, then I know the server can't be found, and if I get anything else, I go ahead and try to connect to it, which for now always seems to work. [sig][/sig]
 
you might get IP_REQ_TIMED_OUT in the following circumstance:

you try and ping a server by a valid name

ping
the name gets resolved to an IP address and some ICMP packets are sent to that IP address

but the server is down... and will never respond

whereas

ping
will (or should) return IP_BAD_DESTINATION because there's no IP address associated with that name

Mike
michael.j.lacey@ntlworld.com
 
Greets,

i am using the above code. It works perfectly as a normal module but when I code it into a dll it gives me the following error:

11001 [ ip buf too_small ]

I am using a normal class module created with vb6. Any obvious thing I am missing?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top