perl网络编程

简单地发起连接
测试连接ftp端口,将打印220 (vsFTPd 2.2.2)

点击(此处)折叠或打开

  1. use Socket;
  2. $proto = getprotobyname('tcp');
  3. my $net_addr = inet_aton("1.1.1.2") or die "aton error $!";
  4. my $sock_addr = sockaddr_in(21, $net_addr) or die "sockaddr error $!";
  5. socket(SOCK, PF_INET, SOCK_STREAM, $proto) or die "sock error ".$!;
  6. connect(SOCK, $sock_addr) or die "connect error $!";
  7. $ret = <SOCK>;
  8. print $ret;



与服务端交互
下面例子连接echo服务,客户端敲什么,服务端就会返回什么。

点击(此处)折叠或打开

  1. use Socket;
  2. use IO::Handle;

  3. my $host = "server2";
  4. my $port = getservbyname("echo", "tcp");
  5. my $proto = getprotobyname("tcp");
  6. $host = inet_aton($host) or die "$host: $!";
  7. socket(SOCK, AF_INET, SOCK_STREAM, $proto) or die "socket: $!";
  8. my $sock_addr = sockaddr_in($port, $host);
  9. connect(SOCK, $sock_addr) or die "connect: $!";
  10. SOCK->autoflush(1); 打开autoflush模式,可以让客户端将信息立刻发出,而不是缓存起来。

  11. my $b_out = 0;
  12. my $b_in = 0;

  13. while(my $msg_out = <>)
  14. {
  15.      print SOCK $msg_out;
  16.      my $msg_in = <SOCK>;
  17.      print $msg_in;
  18.      $b_out += length($msg_out);
  19.      $b_in += length($msg_in);
  20.      last unless $b_out < 10;
  21. }
  22. close SOCK;
  23. say "sent $b_out, recived $b_in";



实现简单的echo服务端

点击(此处)折叠或打开

use 5.010;
use Socket;
use IO::Handle;
my $port = 4444;
my $proto = getprotobyname("tcp");
socket(SOCK, AF_INET, SOCK_STREAM, $proto) or die "socket: $!";
setsockopt(SOCK, SOL_SOCKET, OS_REUSEADDR, 1); 允许服务端崩溃后立刻重新使用以绑定的地址
my $sock_addr = sockaddr_in($port, inet_aton("0.0.0.0"));或者my $sock_addr = sockaddr_in($port, INADDR_ANY);
bind(SOCK, $sock_addr);
listen(SOCK, SOMAXCONN);
say "listen ok";
while(1)
{
        my $remote_addr = accept(CONN, SOCK);
        my $pid = fork();
        next unless $pid == 0;
        my($re_port, $re_addr) = sockaddr_in($remote_addr);
        say "connection from ".inet_ntoa($re_addr).":$re_port";
        CONN->autoflush(1);
        while(<CONN>)
        {
                chomp;
                print CONN reverse."\n";
        }
        say "connection finished from ".inet_ntoa($re_addr).":$re_port";
        close CONN;
}
close SOCK;




用IO::Socket实现的daytime客户端

点击(此处)折叠或打开

use IO::Socket qw(:DEFAULT :crlf); 导出crlf常量和默认常量
my $host = "server2";
$/ = CRLF; 设置行尾分隔符为常量CRLF
my $socket = IO::Socket::INET->new("$host:daytime") or die "socket: $!";
chomp (my $time = $socket->getline);
say $time;


IO::Socket::INET的构造函数很强大,比如这种形式

点击(此处)折叠或打开

  1. my $socket = IO::Socket::INET->new(PeerAddr=>"server2",
  2.         PeerPort=>"daytime(7)",
  3.         Type=>SOCK_STREAM,
  4.         Proto=>"tcp") or die "socket: $!";

监听本地端口:

点击(此处)折叠或打开

  1. my $listen = IO::Socket::INET->new(
  2.      LocalPort=>"4444",
  3.      Type=>SOCK_STREAM,
  4.      Proto=>"tcp",
  5.      Listen=>128) 监听队列长度
  6.      or die "socket: $!"



用面向对象方式实现echo服务端

点击(此处)折叠或打开

use 5.010;
use IO::Socket qw(:DEFAULT :crlf);

$/ = CRLF;
my $sock = IO::Socket::INET->new
     (
     Listen => 128,
     LocalPort => 4444,
     Reuse => 1,
     Timeout => 60*60
     )
     or die "socet: $!";
say "listen ok";
while (1)
{
     next unless my $session = $sock->accept;
     next unless fork eq 0;
     my $peer = gethostbyaddr($session->peeraddr, AF_INET) || $session->peerhost;
     my $port = $session->peerport;
     say "connection from [$peer : $port]";
    
     while(<$session>)
     {
          chomp;
          if($_ eq "quit" or $_ eq "exit") {last};
          my $out = reverse;
          print $session $out;
     }
     say "connection from [$peer : $port] finished";
     close $session;
}
close $sock;


用面向对象风格实现客户端,要求能同时输入和输出
例如实现一个telnet客户端,连接ftp端口

点击(此处)折叠或打开

  1. use strict;
  2. use 5.010;

  3. use IO::Socket qw(:DEFAULT :crlf);
  4. sub to_server
  5. {
  6.      my $server = shift;
  7.      while(<>)
  8.      {
  9.           chomp;
  10.           print $server $_.CRLF;
  11.      }
  12. }

  13. sub from_server
  14. {
  15.      my $server = shift;
  16.      $/ = CRLF;
  17.      while(<$server>)
  18.      {
  19.           chomp;
  20.           say;
  21.      }
  22. }

  23. my $sock = IO::Socket::INET->new("server2:21");
  24. my $child = fork;
  25. if($child)
  26. {
  27.      to_server $sock;
  28.      $sock->shutdown(1);
  29.      sleep;
  30. }
  31. else
  32. {
  33.      from_server $sock;
  34.      say "connection closed by foreign host.";
  35. }

执行
[root@server2 pl]# ./a.pl
220 (vsFTPd 2.2.2)
USER anonymous
331 Please specify the password.
PASS asd
230 Login successful.
help
214-The following commands are recognized.
ABOR ACCT ALLO APPE CDUP CWD  DELE EPRT EPSV FEAT HELP LIST MDTM MKD
MODE NLST NOOP OPTS PASS PASV PORT PWD  QUIT REIN REST RETR RMD  RNFR
RNTO SITE SIZE SMNT STAT STOR STOU STRU SYST TYPE USER XCUP XCWD XMKD
XPWD XRMD
214 Help OK.
quit
221 Goodbye.
connection closed by foreign host.










来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26239116/viewspace-2125608/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/26239116/viewspace-2125608/

你可能感兴趣的:(网络)