Check if socket is connected before sending data
Asked Answered
P

1

9

I'm programming a simple code using socket connection in perl:

$sock = new IO::Socket::INET(
                  PeerAddr => '192.168.10.7',
                  PeerPort => 8000,
                  Proto    => 'tcp');
$sock or die "no socket :$!";

Then sending data using a loop:

while...
print $sock $str;
...loop

Is there a way to insert into the loop a command to check connection? Something like:

while...
   socket is up?
   yes => send data
   no => connect again and the continue with loop
...loop

EDIT ADD MY CODE:

my $sock = new IO::Socket::INET(
                    PeerAddr => '192.168.10.152',
                    PeerPort => 8000,
                    Proto    => 'tcp');
  $sock or die "no socket :$!";

  open(my $fh, '<:encoding(UTF-8)', 'list1.txt')
      or die "Could not open file $!";

  while (my $msdn = <$fh>) {
        my $port="8000";
        my $ip="192.168.10.152";
        unless ($sock->connected) {
          $sock->connect($port, $ip) or die $!;
    }
    my $str="DATA TO SEND: " . $msdn;
    print $sock $str;
  }
  close($sock);
Pep answered 12/9, 2016 at 9:47 Comment(0)
B
17

IO::Socket::INET is a subclass of IO::Socket, which has a connected method.

If the socket is in a connected state the peer address is returned. If the socket is not in a connected state then undef will be returned.

You can use that in your loop and call connect on it if the check returned undef.

my $sock = IO::Socket::INET->new(
    PeerAddr => '192.168.10.7',
    PeerPort => 8000,
    Proto    => 'tcp'
);
$sock or die "no socket :$!";

while ( 1 ) {
    unless ($sock->connected) {
        $sock->connect($port, $ip) or die $!;
    }
    # ...
}
Bagel answered 12/9, 2016 at 9:53 Comment(10)
yes but this is not always enough perldoc.perl.org/IO/Socket.html#connected (should also check return value of ->write())Granophyre
Sorry, but I don't understand. I already have a loop to read a file, line by line and then inside the loop I'm sending data to the server. This works perfect, But, if for some reasons, the server will close the connection, aplication exit without finish sending all the lines. I don't understand how can I implement the: $socket->connect unless $socket->connected; in a way I can create a socket again (connect again) before continue sending data from the loop.Pep
@LucasRey I don't think you need to create a new socket. You just want to reconnect, which this line does. Put it at the top of the loop (my while (1) was just so there is a loop in the example) and write after that. That should do it.Bagel
The connected method in IO::Socket::INET is provided by its base class IO::Socket. And you really should test the success of the connect method in the loop.Stolon
@simbabque: ok clear, thank you. Problem is when the server connection goes down during loop, I receive: "usage: $sock->connect(NAME) or $sock->connect(PORT, ADDR) at ./sms.pl line 67" and the the application exit. :(Pep
@simbabque: well... this: $sock->connect(8000, 192.168.10.7) unless $sock->connected; does not work. The application simply exit after disconnection !!Pep
@lucas you don't have quotes around the IP address. See my edit and add error checking.Bagel
@simbabque: I'm surrendering :( .... Unfortunately I don't know perl very well, Normally I'm programming in other languages. I just tried like your example, and now I got: Bad arg length for Socket::pack_sockaddr_in, length is 14, should be 4 at /usr/lib/perl5/5.8.8/IO/Socket/INET.pm line 224, <$fh> line 39. one question: you used $sock and the $socket, is this a typo? However I still receive the above error when the connection goes down code . MY CODE: my $port="8000"; my $ip="192.168.10.150"; unless ($sock->connected) { $sock->connect($port, $ip) or die $!; }Pep
@lucas yes, that was a typo. But my code here is just an example anyway. Don't directly copy it. You didn't show enough code to make a working program, so you only get examples. Please include your full code in the question.Bagel
@simbabque: Thank you, added my code. With that, after server disconnection I got: Bad arg length for Socket::pack_sockaddr_in, length is 14, should be 4 at /usr/lib/perl5/5.8.8/IO/Socket/INET.pm line 224, <$fh> line 35302.Pep

© 2022 - 2024 — McMap. All rights reserved.