| 首页 | 技术文章 | 软件下载 | 博客 | 论坛 | 精品教程 | 黑客动画 | 视频资源 | 在线服务 | 黑客游戏 | 

您现在的位置: 中国X黑客小组 >> 技术文章 >> 编程技术 >> 黑客编程 >> 文章正文 用户登录 新用户注册
  用Perl POE实现端口重定向         ★★★ 【字体:
用Perl POE实现端口重定向
作者:r00t    文章来源:CnXHacker.Net    点击数:    更新时间:2005-10-3    

POE - Persistent Object Enviroment,http://poe.perl.org

POE是用单线程实现的基于事件驱动的,可协作完成多任务的Perl模块,简单的说,就是在单线程下的状态机,在事件的循环中,有某个注册事件发生时,就调用注册的处理代码。在用Perl做网络编程时,常常需要多进程、线程、监视Socket的IO等并发操作,相关的函数和模块即fork、threads、select,另一个选择就是使用POE单线程的事件驱动来模拟并发的进程和线程,显然单线程下可以方便的共享数据。下面实现TCP端口重定向,例一使用创建子进程和IO::Select;例二采用POE实现。

===========================================================================================
eXample one:端口重定向(fork、IO::Select)
===========================================================================================
#!C:\Perl\bin\perl.exe
#A simple TCP stream forwarder
#By shanleiguang@gmail.com, 2005/10
use strict;
use warnings;

use IO::Socket;
use IO::Select;
use Getopt::Std;
use POSIX qw(:sys_wait_h strftime);

use constant FOREVER => 1;
use constant BUFSIZE => 4096;

#父进程下处理僵死子进程
sub zombie_reaper {
    while(waitpid(-1, WNOHANG) > 0) {}
    $SIG{CHLD} = \&zombie_reaper;
}

$SIG{CHLD} = \&zombie_reaper;

#处理参数
my %opts;
getopts('h:l: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_help() and exit if($opts{'l'} !~ m/^\d+$/);
print_help() and exit if($opts{'p'} !~ m/^\d+$/);

my $listen_port = (defined($opts{'l'})) ? $opts{'l'} : 8080;
my $target_ip   = $opts{'t'};
my $target_port = $opts{'p'};

#在本地创建监听Socket
my $socket_listen  = IO::Socket::INET->new(
    LocalPort => $listen_port,
    Proto     => 'tcp',
    Listen    => 5,
    Reuse     => 1,
);

print timestamp(), ", listening on port $listen_port ...\n";

#新建两个用于Socket IO监视的IO::Select对象
my $readers = IO::Select->new();
my $writers = IO::Select->new();

$readers->add($socket_listen);

#父进程仅监视Listening Socket的accept事件
while(FOREVER) {
    my @readers = $readers->can_read;

    foreach my $reader (@readers) {
        if($reader eq $socket_listen) {
            #创建子进程处理后续的转发,父进程继续监视Listening Socket
            fork and next;

            my $socket_client = $socket_listen->accept();

            #在子进程中,不再需要对Listening Socket进行操作
            $readers->remove($socket_listen);
            $socket_listen->close();

            #子进程
            as_server($socket_client);

            exit;
        }
    }
}

#子进程
sub as_server {
    my $socket_client = shift;

    my $client_port = $socket_client->peerport();
    my $client_ip   = $socket_client->peerhost();

    #创建到目标地址:端口的Socket连接
    my $socket_forward = IO::Socket::INET->new(
        PeerAddr => $target_ip,
        PeerPort => $target_port
    );

    print timestamp(), ", $client_ip:$client_port<->$target_ip:$target_port.\n";

    #监视socket_client、socket_forward的IO情况
    $readers->add($socket_client);
    $readers->add($socket_forward);
    $writers->add($socket_client);
    $writers->add($socket_forward);

    my ($rbuffer_forward, $rbuffer_client) = ('', '');

    while(FOREVER) {
        my @readers = $readers->can_read;

        foreach my $reader (@readers) {
            my $rbuffer;
            #当socket_client可读时,将读取的内容追加到rbuffer_client后
            #假如读取失败,则退出子进程
            if($reader eq $socket_client) {
                exit if(not recv($reader, $rbuffer, BUFSIZE, 0));
                $rbuffer_client.= $rbuffer;
            }

            #当socket_forward可读时,将读取的内容追加到rbuffer_forward后
            #假如读取失败,则退出子进程
            if($reader eq $socket_forward) {
                exit if(not recv($reader, $rbuffer, BUFSIZE, 0));
                $rbuffer_forward.= $rbuffer;
            }
        }

        my @writers = $writers->can_write;

        foreach my $writer (@writers) {
            #当socket_client可写,且rbuffer_forward不为空时,将rbuffer_forward
            #内容写入socket_client,假如写失败,则退出子进程
            if($writer eq $socket_client) {
                next if(not $rbuffer_forward);
                exit if(not send($writer, $rbuffer_forward, 0));
                $rbuffer_forward = '';
            }

            #当socket_forward可写,且rbuffer_client不为空时,将rbuffer_client
            #内容写入socket_forward,假如写失败,则退出子进程
            if($writer eq $socket_forward) {
                next if(not $rbuffer_client);
                exit if(not send($writer, $rbuffer_client, 0));
                $rbuffer_client = '';
            }
        }
    }
}

sub timestamp {
    return strftime "[%y/%m/%d,%H:%M:%S]", localtime;
}

sub print_help {
    my $filename = (split /\\/, $0)[-1];

    print <<HELP

  >>> $filename [-h,-l:] <-t:,-p:>
    -h  print help
    -l  listening local port, default 8080
    -t  target ipaddr
    -p  target port
            By shanleiguang\@gmail.com, 2005/10

HELP
}
===========================================================================================


===========================================================================================
eXample two:端口重定向(POE)
===========================================================================================
POE结构:

Driver->Filter->Wheel->Components
   |______|______|________|
             |
          Session
             |
           Kernel

Driver:    底层文件操作的抽象,在编程时不会直接用到
Filter:    底层、中层协议操作的抽象,通常不会直接用到
Wheel:     高层协议操作的抽象,经常要用到
Components:POE提供的一些拿来就能用的组件
Session:   会话抽象,会话中需要创建高层协议抽象
Kernel:    POE管理会话的内核

POE对象的数据结构:

$_[HEAP]:是会话唯一的数据存储区;
$_[SESSION]:是指向会话自身的引用;
$_[KERNEL]:是指向会话管理内核的引用;
@_[ARG0..ARG9]:用于传递给各事件处理函数的参数;

还是实例最直观:
在父会话中创建一个监听用的Socket,当有客户端连接,即有accept_su

[1] [2] [3] 下一页

文章录入:IceRiver    责任编辑:IceRiver 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    Skype蠕虫(w32/Ramex.A)的
    “Skype蠕虫”病毒技术细节
    Skype用户须警惕新Windows蠕
    Skype提醒用户警惕新P2P蠕虫
    US CERT:谷歌eBay雅虎网站均
    Thomson SpeedTouch 2030 SI
    Asterisk 畸形 MIME 数据时有
    Skype登录故障 成全雅虎Mess
    恶意木马变种通过Skype大肆传
    Skype登录故障 微软否认是祸
      网友评论:(只显示最新5条。评论内容只代表网友观点,与本站立场无关!)
    Powered by ICE RIVER - STUDIO
    » CnXHacker.CoM   © CopyRight 2002-2006, CnXHacker.CoM™, Inc. All Rights Reserved.