|
|
| 首页 | 技术文章 | 软件下载 | 博客 | 论坛 | 精品教程 | 黑客动画 | 视频资源 | 在线服务 | 黑客游戏 | | ||||
|
|
||||||||
|
||||||||
|
|||||
| 用Perl POE实现端口重定向 | |||||
作者:r00t 文章来源:CnXHacker.Net 点击数: 更新时间:2005-10-3 ![]() |
|||||
|
则创建一个子会话处理后续事件,并将accept获得的客户端Socket传递给子会话;子会话 创建到目标的Socket,连接过程中,如果客户端Socket中有input事件,则将客户端的input 内容缓存在一个队列中,当连接成功后,发送给到目标的那个Socket中,见下图: +-------------------------------+ /| Socket_listen | / +-------------------------------+ Client<-->|Socket_client <=> Socket_server|<-->Target +-------------------------------+ Forwarder =========================================================================================== #!C:\Perl\bin\perl.exe #A simple TCP stream forwarder #By shanleiguang@gmail.com, 2005/10 use strict; use warnings; use Socket; use Getopt::Std; use POSIX qw(strftime); use POE qw( Wheel::SocketFactory Wheel::ReadWrite Filter::Stream ); #Get Options my %opts; getopts('hl:t:p:', \%opts); print_help() and exit if(defined($opts{'h'})); print_help() and exit if(not defined($opts{'t'}) or not defined($opts{'p'})); print_help() and exit if($opts{'t'} !~ m/^\d+.\d+.\d+.\d+$/); print_hekp() and exit if($opts{'p'} !~ m/^\d+$/); my $listen_port = (defined($opts{'l'})) ? $opts{'l'} : 8080; my $target_addr = $opts{'t'}; my $target_port = $opts{'p'}; ###Create Parent - 'Listen Session'### ###创建父会话用于监听客户端的连接 ###会话创建的最后将进入_start状态,执行_start的handler ###accept_success即在_start的handler中创建监听Socket的Wheel中 ###的SuccessEvent事件,它的handler是forwarder_create函数 ###$_[ARG0]是wheel::SocketFatory的SuccessEvent传递的参数 POE::Session->create( inline_states => { _start => \&forwarder_server_start, _stop => sub { print timestamp(), ", forwarder server stopped."; }, accept_success => sub { &forwarder_create($_[ARG0]); }, accept_failure => sub { delete $_[HEAP]->{server_wheel} }, }, ); $poe_kernel->run(); exit; ###Event handlers for Parent Session### ###父会话中的事件处理函数 sub forwarder_server_start { print timestamp(), ", listening on port $listen_port and "; print "forward to $target_addr:$target_port\n"; #在父会话的存储区创建一个监听Socket类型的Wheel $_[HEAP]->{server_wheel} = POE::Wheel::SocketFactory->new( BindPort => $listen_port, SocketProtocol => 'tcp', ListenQueue => SOMAXCONN, Reuse => 'on', #ARG0 of SuccessEvent SuccessEvent => 'accept_success', FailureEvent => 'accept_failure', ); } ###Create Child - 'Forward Session'### ###创建子会话 sub forwarder_create { my $socket = shift; POE::Session->create( inline_states => { _start => \&forwarder_start, _stop => sub { print ' ' x 4, timestamp(), ', sessionId:'; print $_[SESSION]->ID, ", forwarder stop\n"; }, client_input => \&client_input, client_error => sub { delete $_[HEAP]->{wheel_client}; delete $_[HEAP]->{wheel_server}; }, server_connect => \&server_connect, server_input => sub { $_[HEAP]->{wheel_client}->put($_[ARG0]) if(exists $_[HEAP]->{wheel_client}); }, server_error => sub { delete $_[HEAP]->{wheel_client}; delete $_[HEAP]->{wheel_server}; }, }, #Parameters to '_start' Event args => [$socket], ); } ##Event Handlers of Child Session## sub forwarder_start { my ($heap, $socket) = @_[HEAP, ARG0]; print ' ' x 4, timestamp(), ', sessionId:'; print $_[SESSION]->ID, ", forwarder start\n"; #Buffer client's input while connecting to the target $heap->{state} = 'connecting'; $heap->{queue} = []; #Client<-'wheel_client'->Forwarder server $heap->{wheel_client} = POE::Wheel::ReadWrite->new( Handle => $socket, Driver => POE::Driver::SysRW->new(), Filter => POE::Filter::Stream->new(), InputEvent => 'client_input', ErrorEvent => 'client_error', ); #Forwarder server<-'wheel_server'->target $heap->{wheel_server} = POE::Wheel::SocketFactory->new( RemoteAddress => $target_addr, RemotePort => $target_port, SuccessEvent => 'server_connect', FailureEvent => 'server_error', ); } sub server_connect { my ($kernel, $session, $heap, $socket) = @_[KERNEL, SESSION, HEAP, ARG0]; #Replace $heap->{wheel_server} $heap->{wheel_server} = POE::Wheel::ReadWrite->new( Handle => $socket, Driver => POE::Driver::SysRW->new, Filter => POE::Filter::Stream->new, InputEvent => 'server_input', ErrorEvent => 'server_error', ); $heap->{state} = 'connected'; $kernel->call($session, 'client_input', $_) foreach(@{$heap->{queue}}); $heap->{queue} = []; } sub client_input { my ($heap, $input) = @_[HEAP, ARG0]; push @{$heap->{queue}}, $input and return if($heap->{state} eq 'connecting'); $heap->{wheel_server}->put($input) if(exists $heap->{wheel_server}); } #Common subroutines sub timestamp { return strftime "[%H:%M:%S]", localtime; } sub print_help { my $filename = (split /\\/, $0)[-1]; print <<HELP >>> $fil |
|||||
| 文章录入:IceRiver 责任编辑:IceRiver | |||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
网友评论:(只显示最新5条。评论内容只代表网友观点,与本站立场无关!) |
| 关于我们 - 版权声明 - 帮助(?) - 广告服务 - 联系我们 - 友情链接 - 用户注册 - | Powered by ICE RIVER - STUDIO |
| » CnXHacker.CoM | © CopyRight 2002-2006, CnXHacker.CoM™, Inc. All Rights Reserved. |