checking a socket status

  • Thread starter Thread starter Abubakar
  • Start date Start date
A

Abubakar

Hi,
lets say I have a connected SOCKET s. At some point in time, I want to know
if the "s" is still valid, that it is still connected. Is there any API that
I can give me this information?

And can I register some callback like thing, that would inform me when "s"
disconnection happens? What I usually do is while I call "send" or "recv", I
get the socket_error and through that I know whats the status. But in this
situation actually I cant wait to call send or recv to know that the socket
is still valid or not.

regards,

Ab.
 
Abubakar said:
lets say I have a connected SOCKET s. At some point in time, I want to know
if the "s" is still valid, that it is still connected. Is there any API that
I can give me this information?

And can I register some callback like thing, that would inform me when "s"
disconnection happens? What I usually do is while I call "send" or "recv", I
get the socket_error and through that I know whats the status. But in this
situation actually I cant wait to call send or recv to know that the socket
is still valid or not.

You can call recv with the zero byte buffer. I'd like to point out that
the programmer should keep track of this sort of things, just as much as
with pointers. There's no function that will tell you whether some
pointer points to a valid object, if you deleted the object then the
pointer is invalid. In the case of sockets, if you called closesocket
then the socket handle is invalid.

The major problem is what if a socket is closed and a new one is opened
with the same value. Any type of check will tell you that "s" is valid,
which is not true.

I deal with this by having a struct that holds a socket, validity flag,
and a reference counter. If the flag is false then the socket is not to
be used/referenced anymore, and when ref_cnt drops to zero destroy the
struct and close the socket.
 
Thanks for the reply.

I will try to explain my design and try to explain why I cant call recv or
send in this case. Whats happening is that I have a seperate thread that has
to send data (to the socket by calling "send" function) *whenever* the data
becomes available, and this thread does nothing else. So naturally I cannot
keep the thread's infinite loop running all the time. So I use
WaitForSingleObject along with a handle created using CreateEvent. The
thread proc is actually a public method of a class that has the infinite
loop. So I have another public method, in the same class lets call it
setMessage(). Let me explain in steps what happens:
1 - something calls setMessage and passes the data to it in its parameter.
2 - setMessage copies this data to some local variable of this class.
3 - setMessage calls the SetEvent
4 - due to SetEvent call, the WaitForSingleObject returns and the next lines
of code takes the copied data and passes it to the "send" socket function.
It then returns and goes again in the waitforsingleobject call and so blocks
again.

Now for client disconnection notifications purposes I need to be informed at
any time when the socket connection breaks so that I can do some gui updates
based on this. But as you have read above, since I'm in a blocking call to
waitforsingleobject, I cant call "send" or recv. Should I have another
thread calling "send" with zero buffer length after equal interval just to
check if this socket connection is going fine or not? This doesnt seems nice
idea to me.

I need suggestion on this design, how could I make it better? How are others
doing it?

Regards,

Ab.
 
Abubakar said:
Now for client disconnection notifications purposes I need to be informed at
any time when the socket connection breaks so that I can do some gui updates
based on this. But as you have read above, since I'm in a blocking call to
waitforsingleobject, I cant call "send" or recv. Should I have another
thread calling "send" with zero buffer length after equal interval just to
check if this socket connection is going fine or not? This doesnt seems nice
idea to me.

Do you ever call recv? If the communication protocol is such that you
only send messages, but don't receive confirmation to them, then there's
a chance that a message that you think is received on the other end
actually isn't received at all.

There are situations when even the TCP/IP stack (in the operating
system) "thinks" that the connection is alive, while it is really dead
(I call them zombie connections). If TCP/IP stack believes this, so
shall you. Your first an last line of defense of these situations is a
communication protocol that facilitates request-response mechanism. If a
response doesn't arrive in a timely fashion (you get to choose the
time-out period) then you declare a time out on a connection and declare
the connection dead for all practical purposes.

The use of such protocol can't be "workarounded" if you need to know
whether the message is *processed* on the other end (and *that* is what
you actually want to know, and not whether the message arrived, or even
whether the connection is broken).
 
Do you ever call recv? If the communication protocol is such that you
only send messages, but don't receive confirmation to them, then there's
a chance that a message that you think is received on the other end

yes I do exactly that. I send a message called "hello" and than the other
end responds in "hello_ack" (while I'm still in recv) after which I indicate
in the gui that the message was successfuly sent. But after gui notification
I have nothing more to do but wait for someone to click on the gui's one
button to send the message again and after which i call recv again to get
the acknowledgment. This cycle repeats. And the way I'm stopping the thread
is through waitforsingleobject as i explained in my previous reply.

Ab.
 
Abubakar said:
yes I do exactly that. I send a message called "hello" and than the other
end responds in "hello_ack" (while I'm still in recv) after which I indicate
in the gui that the message was successfuly sent. But after gui notification
I have nothing more to do but wait for someone to click on the gui's one
button to send the message again and after which i call recv again to get
the acknowledgment. This cycle repeats. And the way I'm stopping the thread
is through waitforsingleobject as i explained in my previous reply.

Why do you need an indication of broken connection? If there is a
response then the connection is valid, if there's no response after a
time-out value then the connection is invalid. You still must use a
time-out functionality, even if you check for connection validity.

Anyway, you could call recv(0) in GUI in timer event handler. Also, you
should call WaitForMultipleObjects (instead of WFSO) with an extra event
that indicates that you should stop waiting, possibly reconnect or
whatever. You set this event if recv(0) returns an error.

Whenever you have secondary threads that may wait on something you
*must* add at least one more event to every waiting list. This event
indicates only that the thread should stop waiting. Every Sleep then
becomes WaitForSingleThread, every WFSO becomes WaitForMultipleThreads,
and every WFMO gets an additional handle in its list. When main thread
should finish it should set that event, wait until all secondary threads
finish, and then finish itself.
 
Anyway, you could call recv(0) in GUI in timer event handler. Also, you
should call WaitForMultipleObjects (instead of WFSO) with an extra event
that indicates that you should stop waiting, possibly reconnect or
whatever. You set this event if recv(0) returns an error.

Sounds like a pretty good idea. I think this technique will solve the
problem.

Thanks.

Ab.
 
Back
Top