Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Timeout for an established connection

by 0day (Sexton)
on Dec 30, 2012 at 14:24 UTC ( #1010925=perlquestion: print w/ replies, xml ) Need Help??
0day has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks.
Tell me please how i can set the timeout for an established connection, which I can not get the data for a long time?
Example http://stockzooi.com/
I handle a lot of sockets with a "poll" in loop:
while (1) { $poll->poll(5); for my $sock ( $poll->handles( POLLHUP | POLLERR | POLLNVAL ) ) { $sock->error(); } for my $sock ( $poll->handles(POLLIN) ) { $sock->recv(); } for my $sock ($poll->handles(POLLOUT)) { $sock->send(); } }

But these connections cannot be processed in this cycle. I did this:
setsockopt($sock, SOL_SOCKET, SO_RCVTIMEO, pack("QQ", 10, 0))
and waited for the error on the socket.
But this does not occur and the connection remains frozen.

Comment on Timeout for an established connection
Select or Download Code
Re: Timeout for timeout for an established connection
by grondilu (Pilgrim) on Dec 30, 2012 at 15:40 UTC

    There is a timeout method in IO::Socket:

    timeout(VAL)

    Set or get the timeout value (in seconds) associated with this socket. If called without any arguments then the current setting is returned. If called with an argument the current setting is changed and the previous value returned.

    Hope this helps.

      timeout method from IO::Socket is not very useful. This timeout value is only used by the connect method.

      no. it does not work. I tried.
Re: Timeout for timeout for an established connection
by zwon (Monsignor) on Dec 30, 2012 at 16:23 UTC

    SO_RCVTIMEO parameter sets timeout for recv call. As you're using poll you have to handle timeouts yourself. After each poll check if there are sockets which didn't have data to read for more than 10 seconds and close them.

      How to do it? Check each socket? Suppose, there is 1000 sockets. Poll said that two of them are available to read. During 0.2 seconds, will be available for 2 more. You say every time check the other 998?
        my $index = $#noreply +1; push @noreply, $obj = HTTP_Request->new($ip, $packet, sub { delete $noreply[$index]; .............. }); .............. .............. my $check_time = time(); my $timeout = 30; while (1) { $poll->poll(5); for my $sock ( $poll->handles( POLLHUP | POLLERR | POLLNVAL )) { $sock->error(); } for my $sock ( $poll->handles(POLLIN) ) { $sock->recv(); } for my $sock ($poll->handles(POLLOUT)) { $sock->send(); } if (time > ($check_time + $timeout)) { $check_time = time; my $i; foreach (@noreply) { if ($_ && $_->ttl < $check_time) { delete $noreply[$i]; $_->close; } ++$i; } } }
        Maybe someone has a more elegant solution?
Re: Timeout for an established connection
by zentara (Archbishop) on Dec 31, 2012 at 11:39 UTC
      Thanks, but... maybe you need to carefully read the question?
        maybe you need to carefully read the question

        I thought I did. :-) IO::Select can be used to set a timeout on reading a socket filehandle. Why aren't you using it? I thought it was in one of the links I listed above.

        FWIW, the method which I found to be workable, comes from the way event-loop systems, like Glib or AnyEvent does it. In those systems, when you you get the meta data from the socket connection that an 'IN' condition has occured, but yet there is no data there to be read, then your connection is caput. See Gtk2 server and client GUI's with root messaging for an example.

        Also see blocking, non-blocking, and semi-blocking, and Knowing when a socket connection is dead for more Select ideas.

        Sorry if I didn't read your question closely enough, but I can't see why select is out of the universe of possible solutions for you. In any event, have a happy new years eve. :-)


        I'm not really a human, but I play one on earth.
        Old Perl Programmer Haiku ................... flash japh
Re: Timeout for an established connection
by BrowserUk (Pope) on Dec 31, 2012 at 13:54 UTC
    how i can set the timeout for an established connection, which I can not get the data for a long time?

    Warning: I've never used IO::Poll. But...

    surely the point of polling, is that you only attempt to do a recv(), when you know there is something available.

    And when something is available, you recv() just what is available, which means the recv() will complete immediately.

    So please explain what you mean by which I can not get the data for a long time"? (The somewhat tortured grammar makes that unclear),

    And explain again, why do you need to set a timeout?


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Ok.
      There is a spider that walks the http links. Spider has a limited number of connections, let it be 10.
      If we run this spider and he will eat 10 such references (http://stockzooi.com/), then it stops working.
      Because IO::Poll, as well as IO::Selekt not notified about the data recv.

      Connection occurs. The data is sent. No response from the server.

      On my computer, the browser tries to open this site 24 hours.
      If the connections is the only one we can close it when the IO::Poll returns zero (timeout).
      But this did not happen, because the remaining 9 connections will be processed normally. Soon the spider will eat one same link. Working connections will remain 8.
      Etc.

        Okay, that explains the problem you are trying to deal with. Ie: when a server accepts a request ($svr->send( GET ... )), but never actually responds.

        By default, the connection will remain open for something like 900 seconds. The solution is to use setsockopt() to set the TCP_USER_TIMEOUT.

        A search for that term will turn up the relevant docs.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1010925]
Approved by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (15)
As of 2014-07-25 13:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (171 votes), past polls