Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: connect() & close()

by tachyon (Chancellor)
on Oct 12, 2004 at 22:21 UTC ( [id://398716]=note: print w/replies, xml ) Need Help??


in reply to connect() & close()

As pg points out once you have sent the data you should be able to close the socket. Closing a socket should not lead to the loss of lingering (aka buffered send) data. As he also points out if you don't close your sockets you may use up all the available file descriptors on your system. They will not time out for at least several hours. On Win32 you will only have ~512 by default. On *nix you should have ~1024 so it is quite easy to use them all if you don't close sockets in a process.

Are you using Socket or IO::Socket::INET? Can you show a short test case? You may find benefit setting the TCP_NODELAY flag to bypass Nagle's algorithm. I found this reference to SO_LINGER on the Socket FAQ

Closing a socket: if SO_LINGER has not been called on a socket, then close() is not supposed to discard data. This is true on SVR4.2 (and, apparently, on all non-SVR4 systems) but apparently not on SVR4; the use of either shutdown() or SO_LINGER seems to be required to guarantee delivery of all data.

NB SVR4 systems include Solaris 2.x, SCO ODT 3.0, AIX, A/UX.

Although I agree with pg that it should not happen why not try calling shutdown on the socket before you close it or specifically setting the TCP_NODELAY and SO_LINGER options. You might also try syswrite to send your data, instead of send. This bypasses both the send interface and stdio.

cheers

tachyon

Replies are listed 'Best First'.
Re^2: connect() & close()
by pg (Canon) on Oct 13, 2004 at 04:53 UTC

    try what tachyon said. In case you need to know the syntax as how to set SO_LINGER, here is an example:

    setsockopt(BROWSER_LISTENER, SOL_SOCKET, SO_LINGER, pack("l", 1)) || d +ie "Failed to setsockopt: $!";
Re^2: connect() & close()
by monktim (Friar) on Oct 13, 2004 at 17:56 UTC
    Thanks for the reply tachyon (and pg). I'm using Perl v5.6.1 build 631 on Win32. I'm also using Socket for TCP. I do have output autoflush on. I have it set at the top of the script $|=1; and I have select((select($socket), $|=1)[0]);

    I tried all combinations of TCP_NODELAY and SO_LINGER but I still didn't get consistent results. Printing to the socket seems to work intermittently when I use those options or when I use no options at all.

    If I call shutdown with 0, 1 or 2 and follow it with a close the msg doesn't get delivered. If I get rid of the close and just call shutdown with a 1 or 2 the msg doesn't get delivered. If I call shutdown($socket, 0) without a following close then the msg does get delivered.

    I found the Socket FAQ to be an excellent resource. Thanks for the link. I found this part especially good. "Nagle's algorithm collects small packets together (no more than .2sec delay) and thereby reduces the amount of overhead bytes being transferred.". This is why the sleep 1; before the close worked. Even though I specified TCP_NODELAY, it appears that it is still buffering.

    I write to the socket like this print $socket (pack("N", length($msg)), $msg); What would a similar syswrite look like? I can't seem to get syswrite to work at all. Syswrite will be my last test before I try and post some code. The sever is written in C++ so I'll have to try and emulate it and I'm not sure I'll have the same results in Perl.

    Thanks again everyone.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://398716]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2024-04-20 02:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found