perl Socket实例

perl Socket实例,第1张

概述Perl socket programming tutorial Socket programming in perl can be done using the low level socket functions or the IO::Socket module.The IO::Socket module provides an object-oriented interface to the

Perl socket programming tutorial
Socket programming in perl can be done using the low level socket functions or the IO::Socket module.The IO::Socket module provIDes an object-orIEnted interface to the socket functions.
In this tutorial we are going to use the low level socket functions.

实例1:连接百度端口80
[root@dou Socket]# cat 1.pl
#!/usr/bin/perl -w

use strict;
# The socket function can be used to create a socket.In the following code example we shall create a tcp socket.
use Socket;

my $proto = getprotobyname('tcp'); # get the tcp protocol
# Create a socket handle(descriptor)
socket(SOCKET,AF_INET,SOCK_STREAM,$proto) or dIE "cant create socket:$!\n";
# Connecting to a Remote Server
my $remote = 'www.baIDu.com';
my $port = 80;
my $iaddr= inet_aton($remote) or dIE "unable to resolve hostname: $remote\n";
my $paddr = sockaddr_in($port,$iaddr); # socket address structure

connect(SOCKET,$paddr) or dIE "connect Failed : $!\n";
print "Connected to $remote on port $port\n";

# Close a socket
close SOCKET,
exit(0);

In the above example we connected to baIDu.com on port 80.
Before the connect function is called the sockaddr_in structure has to be setup.
The sockaddr_in structure stores the information about the remote address,
address type and port number. The inet_aton function converts a hostname/ip to
ip address in long number format.

[root@dou Socket]# cat 1.pl
#!/usr/bin/perl -w

use strict;
# The socket function can be used to create a socket.In the following code example we shall create a tcp socket.
use Socket;
use Encode;

my $proto = getprotobyname('tcp'); # get the tcp protocol
# Create a socket handle(descriptor)
socket(SOCKET,$paddr) or dIE "connect Failed : $!\n";
print "Connected to $remote on port $port\n";

# Send data
# Once connected it's time to start communication by sending some data.The send function can be used for this.
# Send some data to Remote Server - the http GET command
send(SOCKET,"GET / http/1.0\n\n",0) or dIE "send Failed:$!\n";

# Receive reply from server - perl way of reading from stream.
# Can also do recv(SOCKET,$msg,2000,0).
while(my $line = <SOCKET>) {
#       $line = encode_utf8($line);
        $line = encode("utf-8",decode("gbk",$line));#(translate gbk code to utf-8 code)
        print "$line\n";
}
# Close a socket
close SOCKET,
exit(0);

Revise

In the above examples we learned the following socket operations.

1. Create a socket
2. Connect to Remote Server/system.
3. Send data
4. Receive a reply

The socket program we wrote above is called a clIEnt.
A clIEnt connects to a Remote Server for exchange of information/data.
Apart from the clIEnt the other type of socket program we are going to write is called a server.
The server serves data to clIEnts connecting to it.
So lets move on to the next section to do some server programming in perl.

Server

The basic steps for making a server are :

1. Create a socket
2. Bind to a local address and local port
3. Listen for incoming connections
4. Accept incoming connections
5. Communicate the with the newly connected clIEnt - send and receive data.

So a server does not connect out to a system,instead it waits for incoming connections.
We have already seen how to create a socket.
So the next task to make a server would be to bind the socket.
The bind function can be used for this task.

Lets take a quick example

[root@dou Socket]# cat server.pl
#!/usr/bin/perl -w
use strict;
use Socket;
$| = 1;

#create a socket handle(descriptor)
socket(SERVER,(getprotobyname('tcp'))[2]) or dIE "cant create socket :$!\n";
#bind to local port 10000
my $port = 10000;
#the socket is bound to port 10000 and address "any".After bind the socket has to be put in Listen mode.
bind(SERVER,sockaddr_in($port,INADDR_ANY)) or dIE "bind Failed:$!\n";
# Listening the incoming connections
Listen(SERVER,10);
print "Server is Now Listening...\n";
# After calling Listen,the socket is ready to accept incoming connections using the accept function.
This shall be done in a loop so that the program can accept connections again and again.

#accept incoming connections and talt to clIEnts
while(1) {
        my $addrinfo = accept(TALK,SERVER);
        my($port,$iaddr) = sockaddr_in($addrinfo);
        my $clIEnthost = gethostbyaddr($iaddr,AF_INET);
        print "Connection accepted from $clIEnthost:$port\n";
        # send some message to the clIEnt
        print TALK "hello clIEnt how are you\n";
        close TALK;
}

#close the socket
close SERVER;
exit(0);
[root@dou socket]# telnet localhost 10000
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
hello clIEnt how are you
Connection closed by foreign host.

指定server的ip地址:
[root@dou Socket]# cat 2.pl
#!/usr/bin/perl -w
use strict;
use Socket;
$| = 1;

#create a socket handle(descriptor)
socket(SERVER,(getprotobyname('tcp'))[2]) or dIE "cant create socket :$!\n";
#bind to local port 10000
my $port = 10000;
my $server = "192.168.0.6";
my $iaddr = inet_aton($server);
my $paddr = sockaddr_in($port,$iaddr);
#the socket is bound to port 10000 and address "any".After bind the socket has to be put in Listen mode.
bind(SERVER,$paddr) or dIE "bind Failed:$!\n";
# Listening the incoming connections
Listen(SERVER,the socket is ready to accept incoming connections using the accept function. This shall be done in a loop so that the program can accept connections again and again.

#accept incoming connections and talt to clIEnts
while(1) {
        my $addrinfo = accept(TALK,AF_INET);
        print "Connection accepted from $clIEnthost:$port\n";
        # send some message to the clIEnt
        print TALK "hello clIEnt how are you\n";
        close TALK;
}

#close the socket
close SERVER;
exit(0);


高级技术:
Asynchronouse I/O
Multiple clIEnts can be handled by asynchronous event driven I/O. IO::Select can be used for this.
[root@dou Socket]# cat iosocket.pl
#!/usr/bin/perl -w
use strict;
use Socket;
use IO::Select;

$| = 1;
my $socket;
my $servtoclIEnt;
#create a socket handle(descriptor)
my $proto = getprotobyname('tcp');
socket($socket,PF_INET,$proto) or dIE "create socket Failed:$!\n";

#bind to local port
my $port = 10001;
my $server = "192.168.0.6";
my $iaddr = inet_aton($server);
my $paddr = sockaddr_in($port,$iaddr);
bind($socket,$paddr) or dIE "bind Failed:$!\n";

#Listen incoming connections
Listen($socket,10);
print "Server $server on port $port is Now Listening ...\n";

#accept incoming connections and talk to clIEnts
my $select = IO::Select->new();
$select->add($socket);
while(1) {
        my @ready = $select->can_read(0);
        foreach my $select_io(@ready) {
                #new connection read
                if($select_io == $socket) {
                        my $clIEntinfo = accept($servtoclIEnt,$socket);
                        my($clIEntport,$clIEntiaddr) = sockaddr_in($clIEntinfo);
                        my $clIEnthost = gethostbyaddr($clIEntiaddr,AF_INET);
                        print "Connection accepted from $clIEnthost : $clIEntport\n";

                        # send some message to the clIEnt
                        send($servtoclIEnt,"Hello clIEnt[$clIEnthost]! Nice to meet you !\n",0);
                        $select->add($servtoclIEnt);
                }
                # existing clIEnt read
                else {
                        chop(my $clIEntinput = <$select_io>);
                        chop($clIEntinput);
                        if ($clIEntinput =~ /quit/i) {
                                $select->remove($select_io);
                                $select_io->close;
                        }else {
                                print "Received -- $clIEntinput\n";

                                # send reply back to clIEnt
                                send($select_io,"OK : $clIEntinput\n",0);
                        }
                }
        }
}

#close the socket
close $socket;
exit(0);
server端运行命令
[root@dou Socket]# perl iosocket.pl &
[1] 3580
[root@dou Socket]# Server 192.168.0.6 on port 10001 is Now Listening ...

[root@dou Socket]#

客户端访问:下面是服务器返回的信息
[root@dou ~]# telnet 192.168.0.6 10001
Trying 192.168.0.6...
Connected to dou.perl.gov (192.168.0.6).
Escape character is '^]'.
Hello clIEnt[dou.perl.gov]! Nice to meet you !
同时server端也返回信息:
[root@dou Socket]# Connection accepted from dou.perl.gov : 42617

客户端开始发送信息:
ls---->send
OK : ls ---->receive
hello---->send
OK : hello ---->receive
hello world---->send
OK : hello world ---->receive
同时server端也返回信息:
Received -- ls
Received -- hello
Received -- hello world


下面是更经典的iosocket程序:
#!/usr/bin/perl -w
use strict;
use Socket;
use IO::Select;

$| = 1;
my $path = "/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin";
my @paths = split(/:/,$path);
my $hit = 0;
my $command;
my @lines;
my $line;
my $socket;
my $servtoclIEnt;
my $reply;
#create a socket handle(descriptor)
my $proto = getprotobyname('tcp');
socket($socket,10);
print "Server $server on port $port is Now Listening ...\n";

#accept incoming connections and talk to clIEnts
my $select = IO::Select->new();
$select->add($socket);
while(1) {
        my @ready = $select->can_read(0);
        foreach my $select_io(@ready) {
                if($select_io == $socket) {
                        my $clIEntinfo = accept($servtoclIEnt,AF_INET);
                        print "Connection accepted from $clIEnthost : $clIEntport\n";
                        send($servtoclIEnt,0);
                        $select->add($servtoclIEnt);}
                else {
                        while(chop(my $clIEntinput = <$select_io>)) {
                                chop($clIEntinput);
                                $clIEntinput =~ s/^[ \t]*//;
                                if ($clIEntinput =~ /quit/i) {
                                        $select->remove($select_io);
                                        $select_io->close;
                                        last;   # (跳出while循环jump out the loop of while)
                                        #close $socket;
                                        #exit 0;
                                }else {
                                        @lines = split(/[ ]/,$clIEntinput);
                                        chomp($command = $lines[0]);
                                        foreach my $dir (@paths) {
                                                search($dir);
                                                if ($hit == 1) {
                                                        last; # (跳出foreach循环jump out the loop of foreach)
                                                }
                                        }
                                        if ($hit != 0) {
                                                send($select_io,"Command is [$command]:\n",0);
                                                 $reply = `$clIEntinput`;
                                                 #send reply back to clIEnt
                                                 send($select_io,"$reply",0);

                                        } else {
                                                send($select_io,"you enter string [$clIEntinput]\n",0);
                                        }
                                }
                        }
                }
        }
}

#close the socket
close $socket;
exit(0);

sub search {
        my $dir = shift;
        opendir(DIR,"$dir") or dIE "cant open dir:$dir:$!\n";
        my @files = readdir(DIR);
        closedir(DIR);
        foreach my $file (@files) {
                next if ($file =~ m/^\.$/ || $file =~ m/^\.\.$/);
                if ("$file" eq "$command") {
                $hit += 1;
                return(0);
                }  else {
                        $hit = 0;
                }
        }
}


服务器端:
[root@dou Socket]# perl 7.pl &
[1] 3641
[root@dou Socket]# Server 192.168.0.6 on port 10001 is Now Listening ...

[root@dou Socket]# Connection accepted from dou.perl.gov : 33965


客户端:

[root@dou ~]# telnet 192.168.0.6 10001 Trying 192.168.0.6... Connected to dou.perl.gov (192.168.0.6). Escape character is '^]'. Hello clIEnt[dou.perl.gov]! Nice to meet you ! ls Command is [ls]: 1.pl 1.py 2.pl 44.pl 4.pl 5.pl 6.pl 7.pl aaa clIEnt.pl ht.pl iosocket.pl iosocket.pl.orig open_clIEnt.pl server.pl tk.pl      hostname Command is [hostname]: dou.perl.gov                           hostname Command is [hostname]: dou.perl.gov quit Connection closed by foreign host. 上述程序的说明: 1)服务器端perl 7.pl &将程序至于后台运行 2)客户端使用telnet进行测试 3)可以输入linux中常用的命令:比如:ls hostname ifconfig eth0等。并且命令的前面可以有多个空格或者tap键。 4)该程序通过搜索系统$PATH路径来确定输入的string是否是一个命令,如果是系统命令的话将$hit的值加1,程序 通过控制$hit的值来觉得是否输出命令的结果,还是单纯的字符串。  

总结

以上是内存溢出为你收集整理的perl Socket实例全部内容,希望文章能够帮你解决perl Socket实例所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1293031.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存