-
Dec 11th, 2017, 06:56 PM
#1
Thread Starter
Frenzied Member
How does Winsock.State compare to Windows API?
I'm trying to find the equivalent API function to the Winsock object's State property. If I want to know if a given Winsock object is connected, or listening, has had an error, has been remotely closed, or has not yet connected, in VB6 I can use the State property of the Winsock object. What is the equivalent Windows API function? I thought there might be an API function called something like SocketState, that would accept a socket handle as a parameter, and return the current state of the socket. However, I can't find such a function mentioned on MSDN, or else I'm overlooking something. Can somebody here tell me if there's an API function to get the current state of a socket?
-
Dec 12th, 2017, 09:31 AM
#2
Re: How does Winsock.State compare to Windows API?
the API WSAAsyncSelect, callbacks/use gives you a bunch of error code returns and "states", such as connect, read, write, close, accept.
the other wsock32 API can give more code returns, together it is possible to make a global "state" variable.
but, im not sure theres a specific socket state API.
-
Dec 17th, 2017, 05:16 AM
#3
Thread Starter
Frenzied Member
Re: How does Winsock.State compare to Windows API?
Originally Posted by baka
the API WSAAsyncSelect, callbacks/use gives you a bunch of error code returns and "states", such as connect, read, write, close, accept.
the other wsock32 API can give more code returns, together it is possible to make a global "state" variable.
but, im not sure theres a specific socket state API.
According to what I read on MSDN about sockets, there's no way using API to tell if a socket is still connected, other than by trying to send or receive data and detecting a failure. Yet I know that the Winsock OCX is capable of detecting the state it's in, (0 means not connected, 7 means connected), without even having to read or write any data. All I need to do is query the Winsock control's State property. So internally, how is the Winsock OCX control doing this? Is it using some undocumented API functions?
-
Dec 17th, 2017, 09:42 AM
#4
Re: How does Winsock.State compare to Windows API?
sckConnected, tells you a connection is established.
you establish a connection to wsock as well, connect, read, accept, but its not called "Connected", after the handshake, you could say you are connected.
after that, in both winsock and wsock you can not tell if the connection is still there at all without receiving/sending data.
that is why we have timeouts and pings.
-
Dec 17th, 2017, 01:04 PM
#5
Re: How does Winsock.State compare to Windows API?
Originally Posted by Ben321
According to what I read on MSDN about sockets, there's no way using API to tell if a socket is still connected, other than by trying to send or receive data and detecting a failure.
With a syncronous socket, trying a send-call is the easiest way to detect, whether a socket is in an invalid, disconnected state...
Originally Posted by Ben321
Yet I know that the Winsock OCX is capable of detecting the state it's in, (0 means not connected, 7 means connected), without even having to read or write any data.
That's because we have a COM-Class-Instance here, which is handling its SocketHandle(s) asynchronously (managing an internal State-Enum-Variable) -
(with sockets in async-mode there's a whole bunch of Events from which one can internally determine, which state to set the internatl State-Enum to).
When we talk about your own implementation around the Winsock-API - it's up to you to decide whether you do:
- an async implementation (then you will have to do the same as the Winsock-Control, setting an internal State-Variable according to incoming Events)
- or a synchronous implementation (in which case you could use the following - for streaming TCP-sockets)
To quote the MSDN-Docu for the Send-Call: https://msdn.microsoft.com/de-de/lib...(v=vs.85).aspx
"Calling send with a len parameter of zero is permissible and will be treated by implementations as successful. In such cases, send will return zero as a valid value."
So, here is a small synchronous Demo-Socket-Class, which does not support much besides connecting and then "just sitting there" -
but it sports an "IsConnected"-Property which shows how such an Implementation could look like:
Code:
Option Explicit 'name it cSyncSocket, for the Test-Form-Code to work
Private Declare Function WSAStartup& Lib "Ws2_32" (ByVal wVR&, WSAD As Any)
Private Declare Function inet_addr& Lib "Ws2_32" (ByVal Addr$)
Private Declare Function SocketInit& Lib "Ws2_32" Alias "socket" (ByVal af&, ByVal s_type&, ByVal protocol&)
Private Declare Function SocketConnect& Lib "Ws2_32" Alias "connect" (ByVal hS&, Addr As Any, ByVal ALen&)
Private Declare Function SocketSend& Lib "Ws2_32" Alias "send" (ByVal hS&, Buf As Any, ByVal BufLen&, ByVal flags&)
Private Declare Function SocketClose& Lib "Ws2_32" Alias "closesocket" (ByVal hS&)
Private Declare Function WSACleanup& Lib "Ws2_32" ()
Private hSocket As Long
Private Sub Class_Initialize()
Dim W&(100): If WSAStartup(514, W(0)) Then WSAStartup 257, W(0)
hSocket = -1
End Sub
Public Function Connect(ByVal IP$, ByVal Port&) As Boolean
CloseSocket
hSocket = SocketInit(2, 1, 0): If hSocket = -1 Then Exit Function
Dim Addr(0 To 3) As Long
Addr(0) = "&H" & Hex((Port And &HFF) * 256& + Port \ 256) & "0002"
Addr(1) = inet_addr(IP)
If SocketConnect(hSocket, Addr(0), 16) = -1 Then CloseSocket: Exit Function
Connect = True
End Function
Public Function IsConnected() As Boolean
If hSocket <> -1 Then IsConnected = True Else Exit Function
Dim Res As Long
Res = SocketSend(hSocket, Res, 0, 0) 'call send with a length of Zero
If Res <> -1 Then Exit Function 'no error was signaled, everything's fine (and we leave with True)
Select Case Err.LastDllError 'an error was signaled, so we dive a bit deeper to find out which one
Case 10035, 10036 'let's spare out WSAEWOULDBLOCK and WSAEINPROGRESS as causes for "not being connected"
Case Else: IsConnected = False 'every other error is cause enough, to consider the socket "disconnected" (not usable)
End Select
End Function
Public Function CloseSocket()
If hSocket <> -1 Then SocketClose hSocket: hSocket = -1
End Function
Private Sub Class_Terminate()
CloseSocket
WSACleanup
End Sub
I've tested it with the following Form-Code (which needs a Timer1:
Code:
Option Explicit
Private S As New cSyncSocket
Private Sub Form_Load()
Timer1.Enabled = True: Timer1.Interval = 10 'we enable a short intervaled timer, to continously reflect the State in the Caption
S.Connect "127.0.0.1", 80 'I'm connecting to my local IIS-WebServer instance here on Port-80
End Sub
Private Sub Timer1_Timer()
Caption = S.IsConnected
End Sub
Now, after the Form was started (and you have a local WebServer running on your dev-machine)
the Caption shows True...
E.g. when I now simply "close and restart" the IIS-service - then the (lost)
Connection-state was immediately reflected with False in the Form-Caption...
(the concrete LastError in this case was 10054 - WSAECONNRESET... the possible error-states are listed here: https://msdn.microsoft.com/de-de/lib...(v=vs.85).aspx
Olaf
Last edited by Schmidt; Dec 17th, 2017 at 01:07 PM.
-
Dec 17th, 2017, 02:31 PM
#6
Thread Starter
Frenzied Member
Re: How does Winsock.State compare to Windows API?
Originally Posted by Schmidt
With a syncronous socket, trying a send-call is the easiest way to detect, whether a socket is in an invalid, disconnected state...
That's because we have a COM-Class-Instance here, which is handling its SocketHandle(s) asynchronously (managing an internal State-Enum-Variable) -
(with sockets in async-mode there's a whole bunch of Events from which one can internally determine, which state to set the internatl State-Enum to).
When we talk about your own implementation around the Winsock-API - it's up to you to decide whether you do:
- an async implementation (then you will have to do the same as the Winsock-Control, setting an internal State-Variable according to incoming Events)
- or a synchronous implementation (in which case you could use the following - for streaming TCP-sockets)
Thank you. The async mode sounds like what I want then. Could you give me some sample code on how to detect the state (connected or not) of a socket in Async mode? What did you mean by detecting events to determine if it's connected? Your above sample code is only for synchronous mode, which is not the route I want to go. Please provide a sample for detecting the connected state of a socket in async mode.
-
Dec 17th, 2017, 07:54 PM
#7
Re: How does Winsock.State compare to Windows API?
Originally Posted by Ben321
Thank you. The async mode sounds like what I want then.
For that mode a lot of (Sock-hWnd-based) VB6-implemenationsfloat around the internet.
Originally Posted by Ben321
Could you give me some sample code on how to detect the state (connected or not) of a socket in Async mode?
Just tested my example also with one of my async-mode-Sockets from vbRichClient5.cTCPClient -
and it works also with those, because WSAEWOULDBLOCK and WSAEINPROGRESS are already in the exception-list.
Originally Posted by Ben321
What did you mean by detecting events to determine if it's connected?
If you go with one of the above mentioned implementations, which mostly use WSAAsyncSelect:
https://msdn.microsoft.com/de-de/lib...(v=vs.85).aspx
Then in this call one has probably specified FD_READ, FD_WRITE, FD_CONNECT, FD_CLOSE,...
And each incoming Win(Sock)-Msg of the above mentioned Event-types would need to be properly handled
(also with regards to potential Errors in the high-word of each of the above incoming lParams) -
if you do that, then you can quite nicely update some internal State-Variables for your Socket-Handles(Objects) -
or raise your own Events, whatever.
You will need to implement the (Socket)Window-Proc properly anyways, to be able to work stable in async-mode -
so the little "IsConnected" thingy further above is not really needed when everything is done well in the WindowProc -
but as said - the routine would work for async-mode too.
Olaf
-
Dec 19th, 2017, 05:02 PM
#8
Thread Starter
Frenzied Member
Re: How does Winsock.State compare to Windows API?
Originally Posted by Schmidt
Would the standard "select" function work here? Or do I really need to use the more complicated function WSAAsync Select to do this?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|