perl socket编程

前端之家收集整理的这篇文章主要介绍了perl socket编程前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

使用PERL SOCKET API首先需要载入SOCKET模块。 
use Socket; 
====================================================================== 
socket(文件句柄,AF_INET,数据类型,协议类型); 
#建立套接

文件句柄随便找个词就可以了。 
AF_INET为域类型,也可以写为PF_INET。 
数据类型,通常用有两种:SOCK_STREAM、SOCK_DGRAM。 
协议类型,可以用协议号代替,EGP---8、HMP---20、ICMP---1、 
RAW---255、RDP---27、RVD---66、TCP---6、UDP---17、XNS-IDP---22、 
其他---22、ALL---0;也可以用getprotobyname()函数作此参数。

例子:socket(SOCK,SOCK_STREAM,getprotobyname('tcp')); 
语柄为SOCK,套接字以TCP方式传输。 
socket(SS,SOCK_DGRAM,17); 
语柄为SS,套接字以UDP方式传输。

======================================================================= 
connect(文件句柄,sockaddr_in结构体); 
#连接主机

----------------------------------------------- 
sockaddr_in结构体:

$address=inet_aton(地址); 
$port=端口号;

$result=sockaddr_in($port,$address);

#上面的$result就是sockaddr_in结构体,实例:

$address=inet_aton(127.0.0.1); 
$port=80; 
$result=sockaddr_in($port,$address); 
-----------------------------------------------

例子:connect(SOCK,$result);

======================================================================= 
bind(套接字,sockaddr_in结构体); 
#绑定服务器主机地址与端口(用于服务端)

例子:bind(SOCK,$result);

======================================================================= 
listen(套接字,等待连接最大队列数); 
#设置端口状态为监听(用于服务端)

例子:listen(SOCK,10);

======================================================================= 
accept(远程套接字,服务端监听套接字) 
#接收远程数据请求,建立连接(用于服务端)

例子:accept(SESSION,SOCK);

======================================================================= 
close(文件句柄); 
或 
close 文件句柄; 
#关闭套接

例子:close(SOCK); 
close SS;


●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●


说说TCP的网络活动顺序:

======================================================================= 
Client(客户端):

建立套接字socket()->连接到目标主机connect()->打开autoflush模式autoflush()-> 
I/O操作->关闭套接字close()


Server(服务器):

建立套接字socket()->绑定服务器地址与端口bind()->设置监听状态listen()->接受远程套接字accept()-> 
打开autoflush模式autoflush()->I/O操作->关闭套接字close()


●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎
PERL SOCKET API编程实例:

附:I/O操作暂时只使用print()与<>符号。 
======================================================================= 
#!usr/bin/perl 
#客户端 
use IO::Handle; #挂起IO::Handle 
use Socket; #调用SOCKET 
$port=80; #连接远程主机的80端口 
$host='localhost'; #使用环回地址 
$packhost=inet_aton($host); #压缩IP地址 
$address=sockaddr_in($port,$packhost); #压成sockaddr_in格式 
socket(CLIENT,6); #套接字为CLIENT,使用TCP协议 
connect(CLIENT,$address); #连接 
CLIENT->autoflush(1); #开启AUTOFLUSH模式 
$msg_in= #INPUT 
print "IN:$msg_in\n"; #OUTPUT 
close CLIENT; #关闭套接字 
exit 1; #退出程序 
======================================================================= 
#!usr/bin/perl 
#服务端 
use IO::Handle; #挂起IO::Handle 
use Socket; #调用SOCKET 
$port=80; #绑定的服务器主机端口为80 
$address=sockaddr_in($port,INADDR_ANY); #压成sockaddr_in格式,使用INADDR_ANY通配符 
socket(SERVER,getprotobyname('tcp')); #套接字为SERVER,使用TCP协议 
bind(SERVER,$address); #绑定 
listen(SERVER,10); #设置监听状态 
while(1){ #进入I/O交换循环体 
next unless (accept(CLIENT,SERVER)); 
CLIENT->autoflush(1); 
print CLIENT "WHAT DO YOU WANT?\n"; 
close CLIENT;} 
close SERVER; #关闭套接字 
exit 1; #退出程序 
======================================================================= 
实例注解:

1)TCP的client与server代码中有一行'SOCK->autoflush(1);',正常情况下下面的I/O代码是会先进入缓存, 
输出的,但加了上面的代码就可以跳过这一步直接输出了。此代码需要预先加载IO::Handle。

2)INADDR_ANY通配符的值在Socket模块中已经定义了,其值为本地网络适配的所有网络接口(包括环回地址、 
广播地址、多播地址等)。 
◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎
头有点痛,写到这里,下回介绍send()与recv()........:P

[日记文]'send()' and 'recv'[perl_sock 2]

writer:demonalex 
email:demonalex_at_dark2s.org

附接上文的某些内容,最后使用的两个C/S程序中的数据交换部分使用了PERL I/O, 
现在介绍一下PERL语言分配给套接字的‘原装’网络数据交换函数:send()、recv()。 
(这两个函数对UDP协议的作用很大,但对TCP来说其实只能说是等于syswrite()、sysread()。)

====================================================================== 
字节变量=send(套接字,传送数据变量,标志参数);

send()函数用于在套接字进程中发送数据。

send()返回的值是储存所发送的字节大小值的变量;传送数据变量为传输数据的内容; 
标志参数为0(默认值就可以了)。

例子:$bytes=send(SOCK,$data,0);

====================================================================== 
地址变量=recv(套接字,接收后的数据所储存的变量,接收数据的长度,标志参数);

recv()函数用于在套接字进程中接收数据。

recv()返回远程主机的地址变量;第二个参数为接收后的数据所储存的变量;第三个 
参数为所接收数据的长度;标志参数同样为默认值0就可以了。

例子:$address=recv(SOCK,$buffer,$length,0);

====================================================================== 
实验1

#!usr/bin/perl 
#客户端 
use IO::Handle; 
use Socket; 
$port=80; 
$host='localhost'; 
$packhost=inet_aton($host); 
$address=sockaddr_in($port,$packhost); 
socket(CLIENT,6); 
connect(CLIENT,$address); 
CLIENT->autoflush(1); 
recv(CLIENT,$msg_in,length($msg_in),0); 
print "IN:$msg_in\n"; 
close CLIENT; 
exit 1; 
======================================================================= 
#!usr/bin/perl 
#服务端 
use IO::Handle; 
use Socket; 
$port=80; 
$host='localhost'; 
$packhost=inet_aton($host); 
$address=sockaddr_in($port,$packhost); 
socket(SERVER,getprotobyname('tcp')); 
bind(SERVER,$address); 
listen(SERVER,10); 
while(1){ 
next unless (accept(CLIENT,SERVER)); 
CLIENT->autoflush(1); 
$msg_out="WHAT DO YOU WANT?\n"; 
send(CLIENT,$msg_out,0); 
close CLIENT;} 
close SERVER; 
exit 1;

[日记文]udp of perl socket[perl_sock 3]

writer:demonalex 
email:demonalex_at_dark2s.org


继续上文谈到的send()与recv(),这次谈一下它们在udp socket中的应用以及如果使用 
perl socket API来调用UDP。

先看看在UDP中的send()、recv()应用: 
========================================================================== 
字节变量=send(套接字,标志参数,发送地址);

send()函数用于在套接字进程中发送数据。

send()返回的值是储存所发送的字节大小值的变量;传送数据变量为传输数据的内容; 
标志参数为0(默认值就可以了);send()在udp中就多了最后一个参数,‘发送地址’, 
此地址的数据形式为sockaddr_in格式,表示把第二参数‘传送数据变量’发送到此地址中。

例子:$bytes=send(SOCK,$address); 
楼上例子中的$address为sockaddr_in格式。 
========================================================================== 
地址变量=recv(套接字,0); 
========================================================================== 
从楼上的讲解可以知道,在UDP调用中send()比TCP调用时多了一个参数,而recv()与在TCP调用时的 
使用方法完全一致。

------------------------------------------------------------------------ 
UDP网络活动顺序:


Client(客户端): 
建立套接字socket()->发送数据send()->接受数据recv()->关闭套接字close()

Server(服务端): 
建立套接字socket()->绑定地址bind()->接受数据recv()->发送数据send()->关闭套接字close() 
------------------------------------------------------------------------ 
从楼上的流程不难发现UDP中的客户端与服务端的不同之处有两点:1)服务端在建立套接字后多添了一个 
绑定bind()程序,用于使客户端能分辨出服务端的网络地址与端口;2)在send()与recv()步骤上顺序倒过 
来了。 
〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓 
最后可以看看例子,琢磨琢磨: 
━━━━━━━━━━━━━━━━━━━━━━━━━━━ 
#!use/bin/perl -w 
#udp client 
use Socket; #导入Socket库 
$host=$ARGV[0]; #第一参数为主机变量 
$port=$ARGV[1]; #第二参数为端口变量 
$packhost=inet_aton($host); #压缩主机地址 
$address=sockaddr_in($port,$packhost); #压为sockaddr_in模式 
socket(CLIENT,17); #建立UDP套接字 
send(CLIENT,"hi,body!\n",$address); #向套接字发送字符串变量 
recv(CLIENT,$buff,100,0); #接收数据 
print"$buff\n"; #把接收后的数据打入STDOUT 
close CLIENT; #关闭套接字 
exit 1; #退出程序 
¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ 
#!use/bin/perl -w 
#udp server 
use Socket; #导入Socket库 
$localhost=sockaddr_in(4000,INADDR_ANY);#压入sockaddr_in模式,使用了全局本地压缩地址INADDR_ANY保留字 
socket(SERVER,17); #建立UDP套接字 
bind(SERVER,$localhost); #绑定套接字 
while(1){ #进入服务器循环体 
next unless $client=recv(SERVER,0); #如果接收到数据就把数据压入$buff,保留远程地址在$client 
chop($buff); #减去$buff最后的输入符号 
print "$buff\n"; #在$buff变量打入STDOUT 
send(SERVER,"$buff\n",$client); #把$buff发送给客户端 

close SERVER; #关闭套接字 
exit 1; #退出程序 
━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[日记文]Summary[perl_sock 4]

writer:demonalex 
email:demonalex_at_dark2s.org

此文为前三篇文章的总结文。

tcp的服务端I/O结构体: 
----------------------------------------------- 
while(1){ 
next unless (accept(CLIENT,SERVER)); 
CLIENT->autoflush(1); 
print CLIENT "WHAT DO YOU WANT?\n"; 
close CLIENT;} 
----------------------------------------------- 
udp的服务端I/O结构体: 
----------------------------------------------- 
while(1){ 
next unless $client=recv(SERVER,0); 
chop($buff); 
print "$buff\n"; 
send(SERVER,$client); 

-----------------------------------------------

从上面的实例可以看出SERVER的I/O体都是循环体,有一特定条件进行循环 
(我们这里用了死循环while(1)),为了就是使服务端能不停的在监听。

TCP I/O的特征就是在accept()中生成一个客户端的套接字,所有I/O操作都 
在此套接字中进行,当I/O完成后,先把客户端的套接关闭,最后才在程序 
的末端部分关闭服务端的套接字。


UDP I/O的特征就是recv()部分,由于在介绍UDP的那篇文中的实例为通过UDP 
把输入的数据返回到客户端的程序,在服务端中的下一步就应该调用send()了, 
在send()中的最后一个参数为sockaddr_in形式地址,又因为在UDP中不能调用 
accept(),所以无法得知对方的对象在哪里,只能通过recv()的返回值。recv() 
的返回值刚好为对方发送数据的sockaddr_in形式地址。


service


#!/usr/bin/perl -w
use Socket;
use IO::Handle;
socket(SOCK,getprotobyname("tcp"));
setsockopt(SOCK,SOL_SOCKET,SO_REUSEADDR,1);
my $addr=sockaddr_in(3000,INADDR_ANY);
bind(SOCK,$addr);


listen(SOCK,SOMAXCONN);
print "wait for a connect\n";
while(1){
  last if my $addr1=accept(S,SOCK);
}
print "connected\n";
while(1){
# print "connected\n";
 S->autoflush(1);
 $msg_in=<S>;
 print "$msg_in\n";


 }


 close S;


client:

#!/usr/bin/perl -w use Socket; use IO::Handle; socket(SOCK,getprotobyname("tcp")); my $addr=sockaddr_in(3000,inet_aton("localhost")); connect(SOCK,$addr); SOCK->autoflush(1); #$buff=<SOCK>; #STDOUT->autoflush(1); #print $buff; while(1){  print "send msg:\n";  $in=<STDIN>;  if($in =~ /quit/i || $in =~ /q/i)  {     print "bye\n";     exit 1;  }  else  {    print SOCK "$in\n";    #send(SOCK,$in,0);    #$print $buff;  } }

猜你在找的Perl相关文章