博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
perl网络编程
阅读量:2432 次
发布时间:2019-05-10

本文共 4124 字,大约阅读时间需要 13 分钟。

简单地发起连接
测试连接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/

你可能感兴趣的文章
一部刷爆朋友圈的5G短片,看完才知道5G多暖多重要!
查看>>
SDN精华问答 | SDN可以做什么?
查看>>
云评测 | 开发者最有用的开源云监控工具有哪些呢? 这7款神器总有一款适合你!...
查看>>
小团队的微服务之路
查看>>
K8S精华问答 | Kubernetes集群不能正常工作,难道是防火墙问题?
查看>>
5G精华问答 | 什么是5G?5G与LTE有什么关系?
查看>>
虎牙直播在微服务改造方面的实践和总结
查看>>
微服务精华问答 | 在使用微服务架构时,您面临哪些挑战?
查看>>
Kubernetes 调度器实现初探
查看>>
边缘计算精华问答 | 边缘计算有哪些应用场景?
查看>>
数据中台精华问答 | 数据中台和传统数仓的区别是什么?
查看>>
如何用30分钟快速优化家中Wi-Fi?阿里工程师有绝招
查看>>
【C语言】C语言中常用函数源代码【strncpy ,strncat ,strncmp】
查看>>
【Java】【算法练习】题目描述:输入一个整数数组,判断该数组是不是某二叉搜索树的后续遍历的结果。如果是输出yes,不是输出no,数组任意两个数字不相同。
查看>>
【Java】【多线程】—— 多线程篇
查看>>
【计算机网络】—— TCP/IP篇
查看>>
【Java】【算法】——算法篇
查看>>
【Java】【数据库】知识重点——数据库篇
查看>>
【Java】学习总结 —— HashMap之put()方法实现原理
查看>>
【计算机网络】【TCP】如何讲清楚Tcp的三次握手和四次挥手?
查看>>