在本文中,让我们讨论如何使用Perl中的内置套接字模块编写Perl套接字编程。
Perl套接字模块提供了一个对象接口,使创建和使用TCP / UPD套接字更加容易。
本文涵盖以下主题:
- TCP客户端和服务器的Perl示例代码
- UDP客户端和服务器的Perl示例代码
- 使用Select(IO :: Select)读取和写入描述符列表
CPAN模块IO :: Socket :: INET用于执行套接字操作,例如—创建,绑定,连接,监听和关闭套接字。
IO :: Select模块用于获取准备好进行读/写操作的描述符。
Perl TCP客户端和服务器
TCP是面向连接的网络协议。在此示例中,让我们回顾一下Perl代码片段,它将向我们解释简单的客户端和服务器通信。
Perl TCP服务器操作
套接字操作(例如套接字创建,绑定和侦听套接字)由IO :: Socket :: INET模块执行。
下面给出的Perl代码执行以下操作:
- 创建套接字
- 将套接字绑定到地址和端口
- 在端口地址监听套接字
- 接受客户端连接
- 在套接字上执行读/写操作。
#!/usr/bin/perl #tcpserver.pl 使用IO :: Socket :: INET; #每次写入后刷新 $| = 1; 我的($ socket,$ client_socket); 我的($ peeraddress,$ peerport); #创建内部执行的IO :: Socket :: INET模块的对象接口 #在指定的端口地址上创建,绑定和侦听套接字。 $socket = new IO::Socket::INET ( LocalHost => '127.0.0.1', LocalPort => '5000', Proto => 'tcp', Listen => 5, Reuse => 1 ) 或者死"创建套接字时出错:$!\ n”; print "SERVER等待端口上的客户端连接5000"; while(1) { # waiting for new client connection. $client_socket = $ socket- >accept(); # get the host and port number of newly connected client. $ peer_address = $ client_socket->peerhost(); $ peer_port = $ client_socket->peerport(); 打印“接受的新客户端连接来自:$ peeraddress,$ peerport \ n”; # write operation 上 the newly accepted client. $data = “DATA from Server”; print $client_socket “$data\n”; # we can also send the data through IO::Socket::INET module, # $client_socket->send($data); # read operation 上 the newly accepted client $data = <$client_socket>; # we can also read from socket through recv() in IO::Socket::INET # $client_socket->recv($data,1024); print “Received from Client : $data\n”; } $socket->close();
另外,请参阅我们前面的 Perl调试器 文章,了解如何调试Perl代码。
Perl TCP客户端操作
下面给出的Perl代码执行以下操作:
- 创建套接字。
- 在特定端口连接到远程计算机。
- 在套接字上执行读/写操作。
#!/usr/bin/perl #tcpclient.pl 使用IO :: Socket :: INET; #每次写入后刷新 $| = 1; 我的($ socket,$ client_socket); # creating object interface of IO::Socket::INET modules which internally creates # socket, binds and connects to the TCP server running 上 the specific port. $socket = new IO::Socket::INET ( PeerHost => '127.0.0.1', PeerPort => '5000', Proto => 'tcp', ) 或者死"创建套接字时出错:$!\ n”; print “TCP Connection Success.\n”; # read the socket data sent 通过 server. $data = <$socket>; # we can also read from socket through recv() in IO::Socket::INET # $ socket- >recv($data,1024); print “Received from Server : $data\n”; # write 上 the socket to server. $data = “DATA from Client”; print $socket “$data\n”; # we can also send the data through IO::Socket::INET module, # $ socket- >send($data); sleep (10); $socket->close();
注意:您可以使用 Vim编辑器作为Perl IDE 使用perl-support.vim插件。
Perl UDP服务器
下面给出的Perl代码执行以下操作:
- 创建套接字。
- 将套接字绑定到特定端口。
#!/usr/bin/perl #udpserver.pl 使用IO :: Socket :: INET; #每次写入后刷新 $| = 1; 我的($ socket,$ received_data); 我的($ peeraddress,$ peerport); # we call IO::Socket::INET->new() to create the UDP Socket and bound # to specific port number mentioned in LocalPort and there is no need to provide # LocalAddr explicitly as in TCPServer. $socket = new IO::Socket::INET ( LocalPort => '5000', Proto => 'udp', ) 或者死"创建套接字时出错:$!\ n”; while(1) { # read operation 上 the socket $socket->recv($ recieved_data,1024); #get the peerhost and peerport at which the recent data received. $peer_address = $ socket- >peerhost(); $peer_port = $ socket- >peerport(); print "\n($peer_address , $peer_port) said : $recieved_data"; #send the data to the client at which the read/write operations done recently. $data = “data from server\n”; print $socket “$data”; } $socket->close();
Perl UDP客户端
下面给出的Perl代码执行以下操作:
- 创建UDP客户端。
- 连接到特定的UDP服务器。
- 在套接字上执行写和读操作。
#!/usr/bin/perl #udpclient.pl 使用IO :: Socket :: INET; #每次写入后刷新 $| = 1; my ($socket,$data); # We call IO::Socket::INET->new() to create the UDP Socket # and bind with the PeerAddr. $socket = new IO::Socket::INET ( PeerAddr => '127.0.0.1:5000', Proto => 'udp' ) 或者死"创建套接字时出错:$!\ n”; #send operation $data = “data from client”; $socket->send($data); #read operation $data = <$socket>; print “Data received from socket : $data\n ”; sleep(10); $socket->close();
另外,请参阅我们之前的文章以了解 Perl阵列参考.
IO :: Select模块–了解准备好的描述符列表
IO :: Select模块提供以下两个主要功能:
- can_read()返回可用的读取描述符
- can_write()返回可用的写描述符
要了解IO :: Select的用法,我们将在tcpserver代码中使用此模块。
步骤1:创建IO :: Socket对象接口
以下代码段创建了IO :: Socket :: INET模块的对象接口,该模块在内部创建一个套接字,绑定并侦听指定的端口地址。
$socket = new IO::Socket::INET ( LocalHost => '127.0.0.1', LocalPort => '5000', Proto => 'tcp', Listen => 5, Reuse => 1 ) 或者死"ERROR in Socket Creation : $!\n"; $select = IO::Select->new($socket) 或者死"IO::Select $!";
步骤2:向选择对象添加描述符
下面的代码片段将描述符添加到选择对象列表中,以准备好描述符。
@ready_clients = $select->can_read(0); foreach my $fh (@ready_clients) { print $fh ""; if($fh == $socket) { my $new = $ socket- >accept(); $select->add($new); } }
步骤3:获取准备读取的描述符
以下Perl代码片段获取了准备读取的描述符列表。
@ready_clients = $select->can_read(0); foreach my $fh (@ready_clients) { if($fh != $socket) { chomp($data=<$socket>); print $data,"\n"; } }
同样,我们可以对套接字执行写操作。
步骤4:从“选择”列表中删除“客户端套接字描述符”
关闭连接后,可以删除选择插槽的客户端套接字描述符,如下所示。
当我们尝试在远程计算机关闭的套接字上发送/接收数据时,会生成SIGPIPE信号。因此,我们可以为SIGPIPE信号分配信号处理程序,该信号处理程序应从选择列表中删除描述符,如下所示。
# $current_client is the global variable which has the recent file descriptor # 上 which the send/receive operation is tried. ### Handle the PIPE $SIG{PIPE} = sub { ####If we receieved SIGPIPE signal then call Disconnect this client function print "Received SIGPIPE , removing a client..\n"; unless(defined $current_client){ print "No clients to remove!\n"; }else{ $Select->remove($current_client); $current_client->close; } #print Dumper $Self->Select->handles; print "Total connected clients =>".(($Select->count)-1)."<\n"; };
如果您喜欢这篇文章,您可能还会喜欢..
![]() |
![]() |
![]() |
![]() |
代码有一些麻烦– the part with
或者死“创建套接字时出错:$!\ n”;
使用错误的引号(不匹配)