1

I have a very strange scenario. I have a Perl application that receives input from several connections (sockets and pipes). Than I am forwarding the message to a pre-defined destinations (sockets are already opened).

see code example:

our %openSockets;
sub forward_message{
    my ($message,$ip,$port,$proto) = @_;
    my $key = "$ip:$port:$proto";

    my $socket = $openSockets{$key};
    unless ($socket && $socket->connected()){
$|=1;#Setting autoflush
        $socket = new IO::Socket::INET6(
        PeerAddr => $ip,
        PeerPort => $port,
        Proto    => $proto
        ) || die "Can't create socket [$key]"; 
        $openSockets{$key} = $socket;
    }

    #autoflush $sock 1;
    $socket->say($message);
    #$socket->flush();
}

The program works fine on the first few minutes but than - for some reason autoflush stop working and the socket starts to buffer. The socket starts to send chunks of ~1500 bytes.

Currently what seems to help is manually calling the flush function (see commented inline). Can anyone explain why autoflush stop working suddenly after few minutes? Is calling manually to flush a valid and only solution?

FYI - i run strace on the process and made sure its the process that writes the ~1500 bytes chunks (This is not the interface driver that decides to buffer it)

More info if needed: Platfom: Linux Perl version: 5.16 Module Version: 2.69 (INET6) | 1.34 (Socket)

yanger
  • 227
  • 1
  • 3
  • 14
  • 1
    as of version 1.18 autoflush is on by default. – Gerhard Feb 12 '18 at 09:00
  • 4
    Note `$|=1;` doesn't turn on autoflush for the socket, you would want `$socket->autoflush(1);` instead - but it sounds to me like that's not the problem, and I'd suggest investigating and telling us more about the rest of the code. For example: What does *"works fine on the first few minutes"* mean? Are you using `print` or `syswrite` to write to the socket? etc. – haukex Feb 12 '18 at 09:53
  • Well - let me elaborate a bit more: $message is a simple string with 20-50 characters. I want each $message to be sent when i call "say()" function. The "forward_message" function is called once every 1-5 seconds. I am using tcpdump to capture the interface output and here is what i see: In the first few minutes - i get individual messages every 1-5 seconds. after some time I see one big message (truncated) every few minutes. Also - I opened the Socket.pm file and made sure autoflush is set to 1 on the constructor. – yanger Feb 12 '18 at 12:12
  • Please provide `strace` output – ikegami Feb 13 '18 at 17:45

1 Answers1

0

I found a workaround. Not sure it will work as expected if you are using Perl-Threads, but for my small application it works.

$socket->say($message);
$socket->flush();

Manually calling flush will send the message if autoflush failed to do so.

I will open a ticket the the CPAN IO group

yanger
  • 227
  • 1
  • 3
  • 14