Re: Maintain TCP client connection to server?
by Tanktalus (Canon) on Mar 24, 2005 at 02:30 UTC
|
I'll give you pointers. I'll leave working examples to people who have a better guess at what you're trying to do.
Checking out IO::Socket, I see that the socket object has a "connected" method. So something like this:
{
my $socket;
sub getSocket
{
unless ($socket && $socket->connected())
{
$socket = IO::Socket->new(@_);
}
$socket;
}
}
The idea is that you always get the socket each time you need it, and it auto-reconnects. | [reply] [d/l] |
|
|
Hi,
let me be more specific. I'd like to connect to tcp server at the start. Then before each send, I'd like to check if tcp port is still connected, otherwise I should reconnect...
I know the first part, but am not sure how to check whether tcp connection is active and how to reconnect...
Thanks in advance,
regards,
Rob.
| [reply] |
|
|
I know the first part, but am not sure how to check whether tcp connection is active and how to reconnect...
That is exactly what the person who replied was trying to show you. Like Tanktalus, I am a bit fuzzy on the exact details but the code sketched out above is what you want, perhaps modulo some additional checking on what constitues a failed or absent connection. At a minimum you'll have to fill out the parameters for the new() call. And it would be good to make those details easily configurable or overrideable (config file, command line...).
Other than that, any time you need the socket, you would just have to say
my $sock = get_socket();
... anywhere in your code, and it will Just Work™. The first time, it will establish the connection and give you the associated socket. On subsequent calls it will simply hand you back the associated socket. If the connection is ever lost, the subsequent call to get_socket() will re-establish it for you.
Things to think about: what happens when the remote server is completely inaccessible, i.e., someone kicked out the network cable. How do you fail? And if it is transient, how do you deal with retries? Conventional wisdom says that three retries with an increasing delay (e.g. 1.5 seconds, 3 seconds, 4.5 seconds) is usually enough to deal with transient errors.
- another intruder with the mooring in the heart of the Perl
| [reply] [d/l] |
Re: Maintain TCP client connection to server?
by polettix (Vicar) on Mar 24, 2005 at 13:52 UTC
|
Tanktalus suggestion is the right path, even if the use of the connected could probably mislead you (i.e. read carefully the documentation).
Thus, you could benefit of the can_write method in IO::Select, even if I actually suspect that your mileage may vary with the system you're using, and in particular whether it supports a "real" select or not.
A simple, brute force approach could be that of trying to write and see if the write was successful. If the TCP connection broke, you should have some feedback about something gone wrong and thus re-establish the connection.
Flavio.
| [reply] [d/l] [select] |
|
|
Hi,
thanks for info. Well, I have send only TCP connection to server. What I must do is to detect/reconnect tcp connection in less than 2 seconds without writting anything on tcp socket (otherwise alarm will trigger). Is this possible to achieve? Any working example ?
I've tried connected() and can_write, but both do not detect losing tcp connection (I take out utp cable) but all stays in same state... Methods with reading tcp socket are also useless since I'm not receiveing anything....
Thanks in advance,
regards,
Rob.
| [reply] |
|
|
(Please understand that this subthread has become quite Off-Topic here)
What can_write() can really tell you is if the server has closed its connection in a clean way, i.e. sending you a FIN packet that your TCP stack has diligently ACKed, which is the best you can get now.
Changing the system won't help you much, so I'm inclined to tell you that you will not know that your connection is down so fast. Any TCP implementation is based on the fact that the underlying network protocol (i.e. IP) can generate delays that are virtually indistinguishable from network failures; in fact, TCP usually adopts some retry schemes for packets that are not acknowledged, so you definitively have to wait.
Moreover, to check if the server is down you actually have to force the TCP/IP stack to send something to him and have it unacknowledged, and I fear that any implementation is "smart" enough to need real data to make such a check. But here I'm going too deep into the forest, and I don't have the needed light at the moment to make the matter clearer - try to ask to some TCP expert forum, or to read about the TCP implementation in the Linux Kernel.
Flavio
Don't fool yourself.
| [reply] [d/l] |
|
|
Note that what you're doing may not even be possible, depending on your operating system (more specifically, depending on the TCP stack you're using). If perl thinks you're still connected, it's likely because the TCP stack thinks you're still connected. And there's not a darned thing you can do about that, other than switch stacks (generally, this means switching OS's).
| [reply] |
|
|
Re: Maintain TCP client connection to server?
by gellyfish (Monsignor) on Mar 24, 2005 at 14:43 UTC
|
If you are writing to a disconnected stream socket then you will get a SIGPIPE which you can be trapped like:
$SIG{PIPE} = sub { print "WHoah got disconnected" };
You can put any code you want to reconnect and retry the send.
/J\ | [reply] [d/l] [select] |