测试连接ftp端口,将打印220 (vsFTPd 2.2.2)
- use Socket;
- $proto = getprotobyname('tcp');
- my $net_addr = inet_aton("1.1.1.2") or die "aton error $!";
- my $sock_addr = sockaddr_in(21, $net_addr) or die "sockaddr error $!";
- socket(SOCK, PF_INET, SOCK_STREAM, $proto) or die "sock error ".$!;
- connect(SOCK, $sock_addr) or die "connect error $!";
- $ret = <SOCK>;
- print $ret;
下面例子连接echo服务,客户端敲什么,服务端就会返回什么。
- use Socket;
- use IO::Handle;
-
- my $host = "server2";
- my $port = getservbyname("echo", "tcp");
- my $proto = getprotobyname("tcp");
- $host = inet_aton($host) or die "$host: $!";
- socket(SOCK, AF_INET, SOCK_STREAM, $proto) or die "socket: $!";
- my $sock_addr = sockaddr_in($port, $host);
- connect(SOCK, $sock_addr) or die "connect: $!";
- SOCK->autoflush(1); 打开autoflush模式,可以让客户端将信息立刻发出,而不是缓存起来。
-
- my $b_out = 0;
- my $b_in = 0;
-
- while(my $msg_out = <>)
- {
- print SOCK $msg_out;
- my $msg_in = <SOCK>;
- print $msg_in;
- $b_out += length($msg_out);
- $b_in += length($msg_in);
- last unless $b_out < 10;
- }
- close SOCK;
- 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的构造函数很强大,比如这种形式
- my $socket = IO::Socket::INET->new(PeerAddr=>"server2",
- PeerPort=>"daytime(7)",
- Type=>SOCK_STREAM,
- Proto=>"tcp") or die "socket: $!";
监听本地端口:
- my $listen = IO::Socket::INET->new(
- LocalPort=>"4444",
- Type=>SOCK_STREAM,
- Proto=>"tcp",
- Listen=>128) 监听队列长度
- 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端口
- use strict;
- use 5.010;
-
- use IO::Socket qw(:DEFAULT :crlf);
- sub to_server
- {
- my $server = shift;
- while(<>)
- {
- chomp;
- print $server $_.CRLF;
- }
- }
-
- sub from_server
- {
- my $server = shift;
- $/ = CRLF;
- while(<$server>)
- {
- chomp;
- say;
- }
- }
-
- my $sock = IO::Socket::INET->new("server2:21");
- my $child = fork;
- if($child)
- {
- to_server $sock;
- $sock->shutdown(1);
- sleep;
- }
- else
- {
- from_server $sock;
- say "connection closed by foreign host.";
- }
[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/,如需转载,请注明出处,否则将追究法律责任。