Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

How to set a timeout for the socket filehandle generated by POE::Wheel::SocketFactory ?

by sunshine_august (Scribe)
on Dec 30, 2008 at 04:07 UTC ( [id://733168]=perlquestion: print w/replies, xml ) Need Help??

sunshine_august has asked for the wisdom of the Perl Monks concerning the following question:

Hi, all monks:

I am building tcp client/server based on POE::Wheel::SocketFactory and POE::Wheel::ReadWrite, and I want the server side can detect the event that the client side is disconnected from the internet as soon as possible(like someone pull the wire out, or the wire is loose, but the client side is still alive, so no tcp FIN package is sent to the server ).

Originally, I think I can set a timeout for the connection accepted by POE::Wheel::SocketFactory, So I use 'sockopt' against the client socket generated by the SocketFactory like the code below. onWheelSFSuccess() is the handler of 'SuccessEvent' event in POE::Wheel::SocketFactory :

sub onWheelSFSuccess { my ( $heap, $clientSocket, $peerHostN, $peerPort ) = @_[ HEAP, ARG0, ARG1, ARG2 ]; my $peerHost = inet_ntoa($peerHostN); my $timeout = pack( 'll', 5, 0 ); $clientSocket->sockopt(SO_RCVTIMEO, $timeout ); $clientSocket->sockopt(SO_SNDTIMEO, $timeout ); my $ioWheel = POE::Wheel::ReadWrite->new( Handle => $clientSocket, InputEvent => 'onWheelRWInput', ErrorEvent => 'onWheelRWError', Filter => POE::Filter::Stream->new(), ); ......
but, I got the following error complainted:
Can't locate object method "sockopt" via package "FileHandle"

So, I know, the 'clientSocket' is no longer a socket filehande but just a filehandle, it has lost its socket attributes. But how can I set a time out for this 'clientSocket', so I can let the POE::Wheel::ReadWrite trigger an ErrorEvent if it can't send the message out within the timeout?

Or, Is there a better and more convinent way to detect the disconnection of the client side in POE?

  • Comment on How to set a timeout for the socket filehandle generated by POE::Wheel::SocketFactory ?
  • Select or Download Code

Replies are listed 'Best First'.
Re: How to set a timeout for the socket filehandle generated by POE::Wheel::SocketFactory ?
by rcaputo (Chaplain) on Dec 30, 2008 at 06:16 UTC

    The socket is just a plain Perl socket, so all Perl socket rules apply. Whatever normally works for your operating system should be fine.

    POE::Wheel::ReadWrite will send an ErrorEvent as soon as the socket reports a problem.

    The "Invalid argument" error means that one of your parameters to setsockopt() is incorrect, but it doesn't say which. You should inspect the parameters to verify they're correct for your operating system.

      Here is my OS:
      [larry@localhost ]$ uname -a Linux localhost 2.6.21 #1 SMP Mon Nov 3 16:32:36 CST 2008 x86_64 x86_6 +4 x86_64 GNU/Linux
      and I add the setsockopt line just like the following reference:
      http://perldesignpatterns.com/?SocketProgramming

      I can't figure out which param is the evil :(.

        You didn't use the same pack() pattern that perldesignpatterns.com does. That page shows pack('LL', 15, 0) while your original example uses 'll'. Uppercase 'LL' and lowercase 'll' are a bit different.

        Perhaps more importantly, that page explains why it uses 'LL' and how to determine what should work for you. The instructions look good, so I recommend following them (if you haven't already).

        You may wish to carefully compare the example with your code. You may be overlooking some other difference.

Re: How to set a timeout for the socket filehandle generated by POE::Wheel::SocketFactory ?
by BrowserUk (Patriarch) on Dec 30, 2008 at 04:38 UTC
      setsockopt doesn't work neither.
      ... use Socket; use POSIX; use IO::Handle; ... sub onWheelSFSuccess { my ( $heap, $clientSocket, $peerHostN, $peerPort ) = @_[ HEAP, ARG0, ARG1, ARG2 ]; my $peerHost = inet_ntoa($peerHostN); my $timeout = pack( 'll', 5, 0 ); #$clientSocket->sockopt(SO_RCVTIMEO, $timeout ); #$clientSocket->sockopt(SO_SNDTIMEO, $timeout ); setsockopt ( $clientSocket, SOL_SOCKET, SO_RCVTIMEO, $timeout ) or warn "Can't do setdosockotp: $!\n"; setsockopt ( $clientSocket, SOL_SOCKET, SO_SNDTIMEO, $timeout ) or warn "Can't do setdosockotp: $!\n"; my $ioWheel = POE::Wheel::ReadWrite->new( Handle => $clientSocket, InputEvent => 'onWheelRWInput', ErrorEvent => 'onWheelRWError', Filter => POE::Filter::Stream->new(), ); ......
      It complaint :
      Can't do setdosockotp: Invalid argument Can't do setdosockotp: Invalid argument

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://733168]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2024-04-19 13:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found