Сокет Perl (IO::Socket::INET6) не является автоматическим сбросом
У меня очень странный сценарий. У меня есть приложение Perl, которое получает входные данные от нескольких соединений (сокетов и каналов). Чем я пересылаю сообщение по заранее определенным адресатам (сокеты уже открыты).
см. пример кода:
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();
}
Программа работает отлично в первые несколько минут, но затем - по какой-то причине автозапуск перестает работать, и сокет начинает буферизоваться. Сокет начинает отправлять куски размером ~1500 байт.
В настоящее время, кажется, что помогает вручную вызвать функцию сброса (см. Комментарий в строке). Кто-нибудь может объяснить, почему автозапуск перестает работать внезапно через несколько минут? Вызов вручную, чтобы сбросить действительное и единственное решение?
К вашему сведению - я запустил strace для процесса и убедился, что это процесс, который записывает куски ~1500 байт (это не драйвер интерфейса, который решает его буферизовать)
Если необходимо, дополнительная информация: Платформа: Linux Версия Perl: 5.16 Версия модуля: 2.69 (INET6) | 1,34 (розетка)
1 ответ
Я нашел обходной путь. Не уверен, что он будет работать должным образом, если вы используете Perl-Threads, но для моего небольшого приложения это работает.
$socket->say($message);
$socket->flush();
Ручной вызов flush отправит сообщение, если autoflush не смог этого сделать.
Я открою тикет группу CPAN IO