TCP-порт постоянно меняется с Perl LWP в цикле

Я анализирую небольшой пользовательский агент LWP в цикле с помощью анализатора HTTP и заметил, что каждое посещение URL-адреса моего порта продолжает меняться.

Хотя у меня есть небольшой скрипт, также сделанный в VB.Net httpwebrequest, и он не меняет номер моего порта при посещении URL-адреса 10 раз.

Можно ли сохранить статический ip:port при использовании perl?


person user1796805    schedule 29.11.2012    source источник
comment
Хорошо, мы определили, что ваш сценарий VB.net использует поддержку активности (поэтому устанавливается только одно соединение, а затем повторно его использует), а ваш сценарий LWP — нет (поэтому каждое соединение получает новый локальный порт). И что у вас, кажется, возникли проблемы с использованием LWP для поддержки активности. Итак, в этот момент я задаюсь вопросом, почему вас это волнует? В новом локальном порте для новых подключений нет ничего плохого или необычного, а поддержка активности хороша для эффективности (по крайней мере, когда она не вызывает проблем), но в вашем случае это не критично. Какую актуальную проблему вы пытаетесь решить сейчас?   -  person ysth    schedule 30.11.2012


Ответы (1)


Для HTTP-клиента:

use LWP::Protocol::http qw( );

@LWP::Protocol::http::EXTRA_SOCK_OPTS = (
    LocalPort => $port,
);

Если вы также хотите использовать определенный интерфейс,

@LWP::Protocol::http::EXTRA_SOCK_OPTS = (
    LocalAddr => $ip,
    LocalPort => $port,
);

Конечно, вы столкнетесь с проблемами, если порт уже используется, что вероятно, если вы только что использовали его для другого соединения.

use LWP::Protocol::http qw( );
use LWP::UserAgent      qw( );

my $port = 12456;
@LWP::Protocol::http::EXTRA_SOCK_OPTS = (
    LocalPort => 12456,
);

my $ua = LWP::UserAgent->new();
print $ua->get('http://www.example.com/show_port')->content for 1..2;

Вывод:

>script.pl
12456
Can't connect to www.example.com:80 (10048)

LWP::Protocol::http::Socket: connect: 10048 at .../LWP/Protocol/http.pm line 51.

>perl -E"say $^E=10048"
Only one usage of each socket address (protocol/network address/port) is normally permitted

Скорее всего порт не переиспользуется, соединение есть. Вы также можете попробовать повторно использовать соединение, передав keep_alive => 1 конструктору LWP::UserAgent.

use LWP::UserAgent qw( );

my $ua = LWP::UserAgent->new( keep_alive => 1 );
print $ua->get('http://www.example.com/show_port')->content for 1..2;

Вывод:

57842
57842
person ikegami    schedule 29.11.2012
comment
Возможно, вы захотите localize этих переменных пакета. - person friedo; 30.11.2012
comment
хорошо, я совсем не великий кодер, я только начинаю учиться, но, похоже, я не могу заставить его работать. Судя по анализатору постоянно меняет порт. Я пробовал также с Keep Alive, но это не сработало :( - person user1796805; 30.11.2012
comment
@ user1796805: VB.net использует поддержку активности? вы должны быть в состоянии сказать от вашего анализатора - person ysth; 30.11.2012
comment
Вопреки тому, что вы сказали, код, который я разместил, работает так, как я описал. Смотрите обновление. - person ikegami; 30.11.2012
comment
@ysth да, согласно анализатору, он сохраняется в vb.net и не меняет номер. - person user1796805; 30.11.2012
comment
@ikegami странно, я могу использовать script.pl только вовремя, после его использования он больше не запускается, только если я изменю LocalPort, он делает это снова - person user1796805; 30.11.2012
comment
больше не бегать значит что? - person ysth; 30.11.2012
comment
@ysth я имею в виду, что я могу запустить скрипт только 1 раз и проанализировать его, после использования скрипта я не могу запустить его еще раз, не могли бы вы поместить его в цикл, чтобы я мог видеть при многократном запуске, остается ли порт одинаковым. Извините, что так много спрашиваю, но я не могу заставить его работать должным образом :( - person user1796805; 30.11.2012
comment
@ user1796805, я знаю. все что есть в моем посте. В деталях. Какова твоя точка зрения? - person ikegami; 30.11.2012
comment
@ysth, порт помещается в TIMED_WAIT после первого запроса, поэтому он недоступен для второго запроса, если он поступает слишком рано после этого. - person ikegami; 30.11.2012